1 From ba2508d435e61cbcd5af0b6f5178d0d1ea5915ff Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Fri, 11 Jan 2013 11:23:51 +0100
4 Subject: [PATCH 143/366] completion: Use simple wait queues
6 Completions have no long lasting callbacks and therefor do not need
7 the complex waitqueue variant. Use simple waitqueues which reduces the
8 contention on the waitqueue lock.
10 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
12 drivers/net/wireless/orinoco/orinoco_usb.c | 2 +-
13 drivers/usb/gadget/function/f_fs.c | 2 +-
14 drivers/usb/gadget/legacy/inode.c | 4 ++--
15 include/linux/completion.h | 9 ++++-----
16 include/linux/uprobes.h | 1 +
17 kernel/sched/completion.c | 32 +++++++++++++++---------------
18 kernel/sched/core.c | 10 ++++++++--
19 7 files changed, 33 insertions(+), 27 deletions(-)
21 diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
22 index f2cd513..6c0f4c9 100644
23 --- a/drivers/net/wireless/orinoco/orinoco_usb.c
24 +++ b/drivers/net/wireless/orinoco/orinoco_usb.c
25 @@ -697,7 +697,7 @@ static void ezusb_req_ctx_wait(struct ezusb_priv *upriv,
26 while (!ctx->done.done && msecs--)
29 - wait_event_interruptible(ctx->done.wait,
30 + swait_event_interruptible(ctx->done.wait,
34 diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
35 index 12a7906..cf435d8 100644
36 --- a/drivers/usb/gadget/function/f_fs.c
37 +++ b/drivers/usb/gadget/function/f_fs.c
38 @@ -1405,7 +1405,7 @@ static void ffs_data_put(struct ffs_data *ffs)
39 pr_info("%s(): freeing\n", __func__);
41 BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
42 - waitqueue_active(&ffs->ep0req_completion.wait));
43 + swaitqueue_active(&ffs->ep0req_completion.wait));
47 diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
48 index e57f48f..7544a54 100644
49 --- a/drivers/usb/gadget/legacy/inode.c
50 +++ b/drivers/usb/gadget/legacy/inode.c
51 @@ -345,7 +345,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)
52 spin_unlock_irq (&epdata->dev->lock);
54 if (likely (value == 0)) {
55 - value = wait_event_interruptible (done.wait, done.done);
56 + value = swait_event_interruptible (done.wait, done.done);
58 spin_lock_irq (&epdata->dev->lock);
59 if (likely (epdata->ep != NULL)) {
60 @@ -354,7 +354,7 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len)
61 usb_ep_dequeue (epdata->ep, epdata->req);
62 spin_unlock_irq (&epdata->dev->lock);
64 - wait_event (done.wait, done.done);
65 + swait_event (done.wait, done.done);
66 if (epdata->status == -ECONNRESET)
67 epdata->status = -EINTR;
69 diff --git a/include/linux/completion.h b/include/linux/completion.h
70 index 5d5aaae..3fe8d14 100644
71 --- a/include/linux/completion.h
72 +++ b/include/linux/completion.h
74 * Atomic wait-for-completion handler data structures.
75 * See kernel/sched/completion.c for details.
78 -#include <linux/wait.h>
79 +#include <linux/wait-simple.h>
82 * struct completion - structure used to maintain state for a "completion"
87 - wait_queue_head_t wait;
88 + struct swait_head wait;
91 #define COMPLETION_INITIALIZER(work) \
92 - { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
93 + { 0, SWAIT_HEAD_INITIALIZER((work).wait) }
95 #define COMPLETION_INITIALIZER_ONSTACK(work) \
96 ({ init_completion(&work); work; })
97 @@ -73,7 +72,7 @@ struct completion {
98 static inline void init_completion(struct completion *x)
101 - init_waitqueue_head(&x->wait);
102 + init_swait_head(&x->wait);
106 diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
107 index 4a29c75..0a294e9 100644
108 --- a/include/linux/uprobes.h
109 +++ b/include/linux/uprobes.h
111 #include <linux/errno.h>
112 #include <linux/rbtree.h>
113 #include <linux/types.h>
114 +#include <linux/wait.h>
116 struct vm_area_struct;
118 diff --git a/kernel/sched/completion.c b/kernel/sched/completion.c
119 index 8d0f35d..45ebcff 100644
120 --- a/kernel/sched/completion.c
121 +++ b/kernel/sched/completion.c
122 @@ -30,10 +30,10 @@ void complete(struct completion *x)
126 - spin_lock_irqsave(&x->wait.lock, flags);
127 + raw_spin_lock_irqsave(&x->wait.lock, flags);
129 - __wake_up_locked(&x->wait, TASK_NORMAL, 1);
130 - spin_unlock_irqrestore(&x->wait.lock, flags);
131 + __swait_wake_locked(&x->wait, TASK_NORMAL, 1);
132 + raw_spin_unlock_irqrestore(&x->wait.lock, flags);
134 EXPORT_SYMBOL(complete);
136 @@ -50,10 +50,10 @@ void complete_all(struct completion *x)
140 - spin_lock_irqsave(&x->wait.lock, flags);
141 + raw_spin_lock_irqsave(&x->wait.lock, flags);
142 x->done += UINT_MAX/2;
143 - __wake_up_locked(&x->wait, TASK_NORMAL, 0);
144 - spin_unlock_irqrestore(&x->wait.lock, flags);
145 + __swait_wake_locked(&x->wait, TASK_NORMAL, 0);
146 + raw_spin_unlock_irqrestore(&x->wait.lock, flags);
148 EXPORT_SYMBOL(complete_all);
150 @@ -62,20 +62,20 @@ do_wait_for_common(struct completion *x,
151 long (*action)(long), long timeout, int state)
154 - DECLARE_WAITQUEUE(wait, current);
155 + DEFINE_SWAITER(wait);
157 - __add_wait_queue_tail_exclusive(&x->wait, &wait);
158 + swait_prepare_locked(&x->wait, &wait);
160 if (signal_pending_state(state, current)) {
161 timeout = -ERESTARTSYS;
164 __set_current_state(state);
165 - spin_unlock_irq(&x->wait.lock);
166 + raw_spin_unlock_irq(&x->wait.lock);
167 timeout = action(timeout);
168 - spin_lock_irq(&x->wait.lock);
169 + raw_spin_lock_irq(&x->wait.lock);
170 } while (!x->done && timeout);
171 - __remove_wait_queue(&x->wait, &wait);
172 + swait_finish_locked(&x->wait, &wait);
176 @@ -89,9 +89,9 @@ __wait_for_common(struct completion *x,
180 - spin_lock_irq(&x->wait.lock);
181 + raw_spin_lock_irq(&x->wait.lock);
182 timeout = do_wait_for_common(x, action, timeout, state);
183 - spin_unlock_irq(&x->wait.lock);
184 + raw_spin_unlock_irq(&x->wait.lock);
188 @@ -277,12 +277,12 @@ bool try_wait_for_completion(struct completion *x)
189 if (!READ_ONCE(x->done))
192 - spin_lock_irqsave(&x->wait.lock, flags);
193 + raw_spin_lock_irqsave(&x->wait.lock, flags);
198 - spin_unlock_irqrestore(&x->wait.lock, flags);
199 + raw_spin_unlock_irqrestore(&x->wait.lock, flags);
202 EXPORT_SYMBOL(try_wait_for_completion);
203 @@ -311,7 +311,7 @@ bool completion_done(struct completion *x)
204 * after it's acquired the lock.
207 - spin_unlock_wait(&x->wait.lock);
208 + raw_spin_unlock_wait(&x->wait.lock);
211 EXPORT_SYMBOL(completion_done);
212 diff --git a/kernel/sched/core.c b/kernel/sched/core.c
213 index 7b7a0d3..061effa 100644
214 --- a/kernel/sched/core.c
215 +++ b/kernel/sched/core.c
216 @@ -3180,7 +3180,10 @@ void migrate_disable(void)
219 #ifdef CONFIG_SCHED_DEBUG
220 - WARN_ON_ONCE(p->migrate_disable_atomic);
221 + if (unlikely(p->migrate_disable_atomic)) {
227 if (p->migrate_disable) {
228 @@ -3210,7 +3213,10 @@ void migrate_enable(void)
231 #ifdef CONFIG_SCHED_DEBUG
232 - WARN_ON_ONCE(p->migrate_disable_atomic);
233 + if (unlikely(p->migrate_disable_atomic)) {
238 WARN_ON_ONCE(p->migrate_disable <= 0);