]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
task_work: remove fifo ordering guarantee
authorEric Dumazet <edumazet@google.com>
Sat, 29 Aug 2015 02:42:30 +0000 (19:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Sep 2015 20:46:58 +0000 (13:46 -0700)
In commit f341861fb0b ("task_work: add a scheduling point in
task_work_run()") I fixed a latency problem adding a cond_resched()
call.

Later, commit ac3d0da8f329 added yet another loop to reverse a list,
bringing back the latency spike :

I've seen in some cases this loop taking 275 ms, if for example a
process with 2,000,000 files is killed.

We could add yet another cond_resched() in the reverse loop, or we
can simply remove the reversal, as I do not think anything
would depend on order of task_work_add() submitted works.

Fixes: ac3d0da8f329 ("task_work: Make task_work_add() lockless")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Maciej Żenczykowski <maze@google.com>
Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
kernel/task_work.c

index 8727032e3a6fbd6038aa4283a58cf1ce782d37f2..53fa971d000d0b7fff1b63be23007057468bf120 100644 (file)
@@ -18,6 +18,8 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */
  * This is like the signal handler which runs in kernel mode, but it doesn't
  * try to wake up the @task.
  *
+ * Note: there is no ordering guarantee on works queued here.
+ *
  * RETURNS:
  * 0 if succeeds or -ESRCH.
  */
@@ -108,16 +110,6 @@ void task_work_run(void)
                raw_spin_unlock_wait(&task->pi_lock);
                smp_mb();
 
-               /* Reverse the list to run the works in fifo order */
-               head = NULL;
-               do {
-                       next = work->next;
-                       work->next = head;
-                       head = work;
-                       work = next;
-               } while (work);
-
-               work = head;
                do {
                        next = work->next;
                        work->func(work);