Commit 2afafa3b authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] filtered wakeups: wakeup enhancements

From: William Lee Irwin III <wli@holomorphy.com>

This patch provides an additional argument to __wake_up_common() so that the
information wakefunc.patch made waiters ready to receive may be passed to them
by wakers.  This is provided as a separate patch so that the overhead of the
additional argument to __wake_up_common() can be measured in isolation.  No
change in performance was observable here.
parent 2f242854
...@@ -104,17 +104,17 @@ static inline void __remove_wait_queue(wait_queue_head_t *head, ...@@ -104,17 +104,17 @@ static inline void __remove_wait_queue(wait_queue_head_t *head,
list_del(&old->task_list); list_del(&old->task_list);
} }
extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr)); void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key));
extern void FASTCALL(__wake_up_locked(wait_queue_head_t *q, unsigned int mode)); extern void FASTCALL(__wake_up_locked(wait_queue_head_t *q, unsigned int mode));
extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr)); extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr));
#define wake_up(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1) #define wake_up(x) __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, NULL)
#define wake_up_nr(x, nr) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr) #define wake_up_nr(x, nr) __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr, NULL)
#define wake_up_all(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0) #define wake_up_all(x) __wake_up(x, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0, NULL)
#define wake_up_all_sync(x) __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0) #define wake_up_all_sync(x) __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0)
#define wake_up_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE, 1) #define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
#define wake_up_interruptible_nr(x, nr) __wake_up((x),TASK_INTERRUPTIBLE, nr) #define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL)
#define wake_up_interruptible_all(x) __wake_up((x),TASK_INTERRUPTIBLE, 0) #define wake_up_interruptible_all(x) __wake_up(x, TASK_INTERRUPTIBLE, 0, NULL)
#define wake_up_locked(x) __wake_up_locked((x), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE) #define wake_up_locked(x) __wake_up_locked((x), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
#define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1) #define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
......
...@@ -2320,7 +2320,7 @@ EXPORT_SYMBOL(default_wake_function); ...@@ -2320,7 +2320,7 @@ EXPORT_SYMBOL(default_wake_function);
* zero in this (rare) case, and we handle it by continuing to scan the queue. * zero in this (rare) case, and we handle it by continuing to scan the queue.
*/ */
static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, int sync) int nr_exclusive, int sync, void *key)
{ {
struct list_head *tmp, *next; struct list_head *tmp, *next;
...@@ -2329,7 +2329,7 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, ...@@ -2329,7 +2329,7 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
unsigned flags; unsigned flags;
curr = list_entry(tmp, wait_queue_t, task_list); curr = list_entry(tmp, wait_queue_t, task_list);
flags = curr->flags; flags = curr->flags;
if (curr->func(curr, mode, sync, NULL) && if (curr->func(curr, mode, sync, key) &&
(flags & WQ_FLAG_EXCLUSIVE) && (flags & WQ_FLAG_EXCLUSIVE) &&
!--nr_exclusive) !--nr_exclusive)
break; break;
...@@ -2342,12 +2342,13 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, ...@@ -2342,12 +2342,13 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
* @mode: which threads * @mode: which threads
* @nr_exclusive: how many wake-one or wake-many threads to wake up * @nr_exclusive: how many wake-one or wake-many threads to wake up
*/ */
void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode, int nr_exclusive) void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode,
int nr_exclusive, void *key)
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&q->lock, flags); spin_lock_irqsave(&q->lock, flags);
__wake_up_common(q, mode, nr_exclusive, 0); __wake_up_common(q, mode, nr_exclusive, 0, key);
spin_unlock_irqrestore(&q->lock, flags); spin_unlock_irqrestore(&q->lock, flags);
} }
...@@ -2358,7 +2359,7 @@ EXPORT_SYMBOL(__wake_up); ...@@ -2358,7 +2359,7 @@ EXPORT_SYMBOL(__wake_up);
*/ */
void fastcall __wake_up_locked(wait_queue_head_t *q, unsigned int mode) void fastcall __wake_up_locked(wait_queue_head_t *q, unsigned int mode)
{ {
__wake_up_common(q, mode, 1, 0); __wake_up_common(q, mode, 1, 0, NULL);
} }
/** /**
...@@ -2386,7 +2387,7 @@ void fastcall __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exc ...@@ -2386,7 +2387,7 @@ void fastcall __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exc
sync = 0; sync = 0;
spin_lock_irqsave(&q->lock, flags); spin_lock_irqsave(&q->lock, flags);
__wake_up_common(q, mode, nr_exclusive, sync); __wake_up_common(q, mode, nr_exclusive, sync, NULL);
spin_unlock_irqrestore(&q->lock, flags); spin_unlock_irqrestore(&q->lock, flags);
} }
EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */ EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */
...@@ -2398,7 +2399,7 @@ void fastcall complete(struct completion *x) ...@@ -2398,7 +2399,7 @@ void fastcall complete(struct completion *x)
spin_lock_irqsave(&x->wait.lock, flags); spin_lock_irqsave(&x->wait.lock, flags);
x->done++; x->done++;
__wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, __wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,
1, 0); 1, 0, NULL);
spin_unlock_irqrestore(&x->wait.lock, flags); spin_unlock_irqrestore(&x->wait.lock, flags);
} }
EXPORT_SYMBOL(complete); EXPORT_SYMBOL(complete);
...@@ -2410,7 +2411,7 @@ void fastcall complete_all(struct completion *x) ...@@ -2410,7 +2411,7 @@ void fastcall complete_all(struct completion *x)
spin_lock_irqsave(&x->wait.lock, flags); spin_lock_irqsave(&x->wait.lock, flags);
x->done += UINT_MAX/2; x->done += UINT_MAX/2;
__wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, __wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE,
0, 0); 0, 0, NULL);
spin_unlock_irqrestore(&x->wait.lock, flags); spin_unlock_irqrestore(&x->wait.lock, flags);
} }
EXPORT_SYMBOL(complete_all); EXPORT_SYMBOL(complete_all);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment