]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/meta-ti-glsdk.git/blob - recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.14/0093-SUNRPC-We-must-not-use-list_for_each_entry_safe-in-r.patch
linux-ti335x-psp 3.2: update to 3.2.14
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.2 / 3.2.14 / 0093-SUNRPC-We-must-not-use-list_for_each_entry_safe-in-r.patch
1 From cdc2a3f4e2494e413531264d3949ce6801123ad9 Mon Sep 17 00:00:00 2001
2 From: Trond Myklebust <Trond.Myklebust@netapp.com>
3 Date: Mon, 19 Mar 2012 13:39:35 -0400
4 Subject: [PATCH 093/147] SUNRPC: We must not use list_for_each_entry_safe()
5  in rpc_wake_up()
7 commit 540a0f7584169651f485e8ab67461fcb06934e38 upstream.
9 The problem is that for the case of priority queues, we
10 have to assume that __rpc_remove_wait_queue_priority will move new
11 elements from the tk_wait.links lists into the queue->tasks[] list.
12 We therefore cannot use list_for_each_entry_safe() on queue->tasks[],
13 since that will skip these new tasks that __rpc_remove_wait_queue_priority
14 is adding.
16 Without this fix, rpc_wake_up and rpc_wake_up_status will both fail
17 to wake up all functions on priority wait queues, which can result
18 in some nasty hangs.
20 Reported-by: Andy Adamson <andros@netapp.com>
21 Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
22 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
23 ---
24  net/sunrpc/sched.c |   15 +++++++++++----
25  1 file changed, 11 insertions(+), 4 deletions(-)
27 diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
28 index 00a1a2a..4e2b3b4 100644
29 --- a/net/sunrpc/sched.c
30 +++ b/net/sunrpc/sched.c
31 @@ -500,14 +500,18 @@ EXPORT_SYMBOL_GPL(rpc_wake_up_next);
32   */
33  void rpc_wake_up(struct rpc_wait_queue *queue)
34  {
35 -       struct rpc_task *task, *next;
36         struct list_head *head;
37  
38         spin_lock_bh(&queue->lock);
39         head = &queue->tasks[queue->maxpriority];
40         for (;;) {
41 -               list_for_each_entry_safe(task, next, head, u.tk_wait.list)
42 +               while (!list_empty(head)) {
43 +                       struct rpc_task *task;
44 +                       task = list_first_entry(head,
45 +                                       struct rpc_task,
46 +                                       u.tk_wait.list);
47                         rpc_wake_up_task_queue_locked(queue, task);
48 +               }
49                 if (head == &queue->tasks[0])
50                         break;
51                 head--;
52 @@ -525,13 +529,16 @@ EXPORT_SYMBOL_GPL(rpc_wake_up);
53   */
54  void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
55  {
56 -       struct rpc_task *task, *next;
57         struct list_head *head;
58  
59         spin_lock_bh(&queue->lock);
60         head = &queue->tasks[queue->maxpriority];
61         for (;;) {
62 -               list_for_each_entry_safe(task, next, head, u.tk_wait.list) {
63 +               while (!list_empty(head)) {
64 +                       struct rpc_task *task;
65 +                       task = list_first_entry(head,
66 +                                       struct rpc_task,
67 +                                       u.tk_wait.list);
68                         task->tk_status = status;
69                         rpc_wake_up_task_queue_locked(queue, task);
70                 }
71 -- 
72 1.7.9.4