wait: Return number of exclusive waiters awaken

commit ee7dc86b6d upstream.

Sbitmap code will need to know how many waiters were actually woken for
its batched wakeups implementation.  Return the number of woken
exclusive waiters from __wake_up() to facilitate that.

Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20221115224553.23594-3-krisman@suse.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Gabriel Krisman Bertazi 2022-11-15 17:45:52 -05:00 committed by Greg Kroah-Hartman
parent 12815a7d8f
commit d710b1e91b
2 changed files with 12 additions and 8 deletions

View File

@ -209,7 +209,7 @@ __remove_wait_queue(struct wait_queue_head *wq_head, struct wait_queue_entry *wq
list_del(&wq_entry->entry); list_del(&wq_entry->entry);
} }
void __wake_up(struct wait_queue_head *wq_head, unsigned int mode, int nr, void *key); int __wake_up(struct wait_queue_head *wq_head, unsigned int mode, int nr, void *key);
void __wake_up_locked_key(struct wait_queue_head *wq_head, unsigned int mode, void *key); void __wake_up_locked_key(struct wait_queue_head *wq_head, unsigned int mode, void *key);
void __wake_up_locked_key_bookmark(struct wait_queue_head *wq_head, void __wake_up_locked_key_bookmark(struct wait_queue_head *wq_head,
unsigned int mode, void *key, wait_queue_entry_t *bookmark); unsigned int mode, void *key, wait_queue_entry_t *bookmark);

View File

@ -121,11 +121,12 @@ static int __wake_up_common(struct wait_queue_head *wq_head, unsigned int mode,
return nr_exclusive; return nr_exclusive;
} }
static void __wake_up_common_lock(struct wait_queue_head *wq_head, unsigned int mode, static int __wake_up_common_lock(struct wait_queue_head *wq_head, unsigned int mode,
int nr_exclusive, int wake_flags, void *key) int nr_exclusive, int wake_flags, void *key)
{ {
unsigned long flags; unsigned long flags;
wait_queue_entry_t bookmark; wait_queue_entry_t bookmark;
int remaining = nr_exclusive;
bookmark.flags = 0; bookmark.flags = 0;
bookmark.private = NULL; bookmark.private = NULL;
@ -134,10 +135,12 @@ static void __wake_up_common_lock(struct wait_queue_head *wq_head, unsigned int
do { do {
spin_lock_irqsave(&wq_head->lock, flags); spin_lock_irqsave(&wq_head->lock, flags);
nr_exclusive = __wake_up_common(wq_head, mode, nr_exclusive, remaining = __wake_up_common(wq_head, mode, remaining,
wake_flags, key, &bookmark); wake_flags, key, &bookmark);
spin_unlock_irqrestore(&wq_head->lock, flags); spin_unlock_irqrestore(&wq_head->lock, flags);
} while (bookmark.flags & WQ_FLAG_BOOKMARK); } while (bookmark.flags & WQ_FLAG_BOOKMARK);
return nr_exclusive - remaining;
} }
/** /**
@ -147,13 +150,14 @@ static void __wake_up_common_lock(struct wait_queue_head *wq_head, unsigned int
* @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
* @key: is directly passed to the wakeup function * @key: is directly passed to the wakeup function
* *
* If this function wakes up a task, it executes a full memory barrier before * If this function wakes up a task, it executes a full memory barrier
* accessing the task state. * before accessing the task state. Returns the number of exclusive
* tasks that were awaken.
*/ */
void __wake_up(struct wait_queue_head *wq_head, unsigned int mode, int __wake_up(struct wait_queue_head *wq_head, unsigned int mode,
int nr_exclusive, void *key) int nr_exclusive, void *key)
{ {
__wake_up_common_lock(wq_head, mode, nr_exclusive, 0, key); return __wake_up_common_lock(wq_head, mode, nr_exclusive, 0, key);
} }
EXPORT_SYMBOL(__wake_up); EXPORT_SYMBOL(__wake_up);