standardized waitqueue hashing
Subsystems (6)
cover standardized waitqueue hashing
The following patch series consolidates the various instances of waitqueue hashing to use a uniform structure and share the per-zone hashtable among all waitqueue hashers. This is expected to increase the number of hashtable buckets available for waiting on bh's and inodes and eliminate statically allocated kernel data structures for greater node locality and reduced kernel image size. Some attempt was made to look similar to Oleg Nesterov's suggested API in order to provide some kind of credit for independent invention of something very similar (the original versions of these patches predated my public postings on the subject of filtered waitqueues).
These patches have the further benefit and intention of enabling aio to use filtered wakeups by standardizing the data structure passed to wake functions so that embedded waitqueue elements in aio structures may be succesfully passed to the filtered wakeup wake functions, though this patch series doesn't implement that particular functionality.
Successfully stress-tested on x86-64, and ia64 in recent prior versions.
-- wli
PATCH 1/5 move waitqueue functions to kernel/wait.c
Quoted 6 lines · William Lee Irwin III
These patches have the further benefit and intention of enabling aio to use filtered wakeups by standardizing the data structure passed to wake functions so that embedded waitqueue elements in aio structures may be succesfully passed to the filtered wakeup wake functions, though this patch series doesn't implement that particular functionality. Successfully stress-tested on x86-64, and ia64 in recent prior versions.
Move waitqueue -related functions not needing static functions in sched.c to kernel/wait.c
kernel/Makefile +1 -1
@@ -7,7 +7,7 @@ sysctl.o capability.o ptrace.o timer.o user.o \ signal.o sys.o kmod.o workqueue.o pid.o \ rcupdate.o intermodule.o extable.o params.o posix-timers.o \ - kthread.o + kthread.o wait.o obj-$(CONFIG_FUTEX) += futex.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
kernel/wait.c new file +129 -0
129 lines not on this page · raw message
kernel/fork.c +0 -125
131 lines not on this page · raw message
PATCH 2/5 consolidate bit waiting code patterns
Quoted 2 lines · William Lee Irwin III
Move waitqueue -related functions not needing static functions in
sched.ctokernel/wait.c
Eliminate specialized page and bh waitqueue hashing structures in favor of a standardized structure, using wake_up_bit() to wake waiters using the standardized wait_bit_key structure.
fs/buffer.c +8 -44
@@ -43,26 +43,6 @@#define BH_ENTRY (list) list_entry((list), struct buffer_head, b_assoc_buffers) -struct bh_wait_queue { -struct buffer_head *bh; -wait_queue_t wait; -}; - -#define __DEFINE_BH_WAIT (name, b, f) \ - struct bh_wait_queue name = { \ - .bh = b, \ - .wait = { \ - .task = current, \ - .flags = f, \ - .func = bh_wake_function, \ - .task_list = \ - LIST_HEAD_INIT(name.wait.task_list),\ - }, \ - } -#define DEFINE_BH_WAIT (name, bh) __DEFINE_BH_WAIT(name, bh, 0) -#define DEFINE_BH_WAIT_EXCLUSIVE (name, bh) \ - __DEFINE_BH_WAIT(name, bh, WQ_FLAG_EXCLUSIVE) -/* * Hashed waitqueue_head's for wait_on_buffer() */
@@ -93,24 +73,10 @@wait_queue_head_t *wq =bh_waitq_head (bh);smp_mb (); -if (waitqueue_active (wq)) -__wake_up (wq,TASK_INTERRUPTIBLE |TASK_UNINTERRUPTIBLE ,1 , bh); +__wake_up_bit (wq, &bh->b_state, BH_Lock); }EXPORT_SYMBOL (wake_up_buffer); -static int bh_wake_function (wait_queue_t *wait,unsigned mode, -int sync,void *key) -{ -struct buffer_head *bh = key; -struct bh_wait_queue *wq; - - wq = container_of(wait, struct bh_wait_queue, wait); -if (wq->bh != bh ||buffer_locked (bh)) -return 0 ; -else -return autoremove_wake_function (wait, mode, sync, key); -} -static void sync_buffer (struct buffer_head *bh) {struct block_device *bd;
@@ -124,7 +90,7 @@ void fastcall __lock_buffer(struct buffer_head *bh) { wait_queue_head_t *wqh = bh_waitq_head(bh); - DEFINE_BH_WAIT_EXCLUSIVE(wait, bh); + DEFINE_WAIT_BIT(wait, &bh->b_state, BH_Lock); do { prepare_to_wait_exclusive(wqh, &wait.wait,
@@ -153,15 +119,13 @@void __wait_on_buffer (struct buffer_head * bh) {wait_queue_head_t *wqh =bh_waitq_head (bh); -DEFINE_BH_WAIT (wait, bh); +DEFINE_WAIT_BIT (wait, &bh->b_state, BH_Lock); -do { -prepare_to_wait (wqh, &wait.wait,TASK_UNINTERRUPTIBLE ); -if (buffer_locked (bh)) { -sync_buffer (bh); -io_schedule (); - } - }while (buffer_locked (bh)); +prepare_to_wait (wqh, &wait.wait,TASK_UNINTERRUPTIBLE ); +if (buffer_locked (bh)) { +sync_buffer (bh); +io_schedule (); + }finish_wait (wqh, &wait.wait); }
kernel/wait.c +23 -0
@@ -127,3 +127,26 @@return ret; }EXPORT_SYMBOL (autoremove_wake_function); + +int wake_bit_function (wait_queue_t *wait,unsigned mode,int sync,void *arg) +{ +struct wait_bit_key *key = arg; +struct wait_bit_queue *wait_bit + = container_of(wait, struct wait_bit_queue, wait); + +if (wait_bit->key.flags != key->flags || + wait_bit->key.bit_nr != key->bit_nr || +test_bit (key->bit_nr, key->flags)) +return 0 ; +else +return autoremove_wake_function (wait, mode, sync, key); +} +EXPORT_SYMBOL (wake_bit_function); + +void fastcall __wake_up_bit(wait_queue_head_t *wq, void *word, int bit) +{ +struct wait_bit_key key =__WAIT_BIT_KEY_INITIALIZER (word, bit); +if (waitqueue_active (wq)) +__wake_up (wq,TASK_INTERRUPTIBLE |TASK_UNINTERRUPTIBLE ,1 , &key); +} +EXPORT_SYMBOL (__wake_up_bit);
mm/filemap.c +9 -54
97 lines not on this page · raw message
include/linux/wait.h +26 -0
@@ -37,6 +37,16 @@struct list_head task_list; }; +struct wait_bit_key { +void *flags; +int bit_nr; +}; + +struct wait_bit_queue { +struct wait_bit_key key; +wait_queue_t wait; +}; +struct __wait_queue_head {spinlock_t lock;struct list_head task_list;
@@ -63,6 +73,9 @@#define DECLARE_WAIT_QUEUE_HEAD (name) \ wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) +#define __WAIT_BIT_KEY_INITIALIZER (word, bit) \ + { .flags = word, .bit_nr = bit, } +static inline void init_waitqueue_head (wait_queue_head_t *q) { q->lock =SPIN_LOCK_UNLOCKED ;
@@ -125,6 +138,7 @@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_sync (wait_queue_head_t *q,unsigned int mode,int nr)); +void FASTCALL (__wake_up_bit (wait_queue_head_t *,void *,int ));#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, NULL)
@@ -277,6 +291,7 @@ wait_queue_t *wait, int state));void FASTCALL (finish_wait (wait_queue_head_t *q,wait_queue_t *wait));int autoremove_wake_function (wait_queue_t *wait,unsigned mode,int sync,void *key); +int wake_bit_function (wait_queue_t *wait,unsigned mode,int sync,void *key);#define DEFINE_WAIT (name) \ wait_queue_t name = { \
@@ -287,6 +302,17 @@ }, \ } +#define DEFINE_WAIT_BIT (name, word, bit) \ + struct wait_bit_queue name = { \ + .key = __WAIT_BIT_KEY_INITIALIZER(word, bit), \ + .wait = { \ + .task = current, \ + .func = wake_bit_function, \ + .task_list = \ + LIST_HEAD_INIT(name.wait.task_list), \ + }, \ + } +#define init_wait (wait) \ do { \ wait->task = current; \
PATCH 3/5 consolidate bit waiting code patterns
Quoted 3 lines · William Lee Irwin III
Eliminate specialized page and bh waitqueue hashing structures in favor of a standardized structure, using
wake_up_bit()to wake waiters using the standardizedwait_bit_keystructure.
Consolidate bit waiting code patterns for page waitqueues using __wait_on_bit() and __wait_on_bit_lock().
kernel/wait.c +37 -0
@@ -143,6 +143,43 @@ }EXPORT_SYMBOL (wake_bit_function); +/* +* To allow interruptible waiting and asynchronous (i.e. nonblocking) +* waiting, the actions of __wait_on_bit() and __wait_on_bit_lock() are +* permitted return codes. Nonzero return codes halt waiting and return. +*/ +int __sched __wait_on_bit(wait_queue_head_t *wq, struct wait_bit_queue *q, +void *word, +int bit,int (*action)(void *),unsigned mode) +{ +int ret =0 ; + +prepare_to_wait (wq, &q->wait, mode); +if (test_bit (bit, word)) + ret = (*action)(word); +finish_wait (wq, &q->wait); +return ret; +} +EXPORT_SYMBOL (__wait_on_bit); + +int __sched __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, +void *word,int bit, +int (*action)(void *),unsigned mode) +{ +int ret =0 ; + +while (test_and_set_bit (bit, word)) { +prepare_to_wait_exclusive (wq, &q->wait, mode); +if (test_bit (bit, word)) { +if ((ret = (*action)(word))) +break ; + } + } +finish_wait (wq, &q->wait); +return ret; +} +EXPORT_SYMBOL (__wait_on_bit_lock); + void fastcall __wake_up_bit(wait_queue_head_t *wq, void *word, int bit) {struct wait_bit_key key =__WAIT_BIT_KEY_INITIALIZER (word, bit);
mm/filemap.c +17 -22
@@ -132,9 +132,11 @@ }EXPORT_SYMBOL (remove_from_page_cache); -static inline int sync_page (struct page *page) +static int sync_page (void *word) {struct address_space *mapping; +struct page *page + = container_of((page_flags_t *)word, struct page, flags);/* * FIXME, fercrissake. What is this barrier here for?
@@ -142,7 +144,8 @@smp_mb (); mapping =page_mapping (page);if (mapping && mapping->a_ops && mapping->a_ops->sync_page) -return mapping->a_ops->sync_page (page); + mapping->a_ops->sync_page (page); +io_schedule ();return 0 ; }
@@ -362,19 +365,19 @@return &zone->wait_table[hash_ptr (page, zone->wait_table_bits)]; } +static inline void wake_up_page (struct page *page,int bit) +{ +__wake_up_bit (page_waitqueue (page), &page->flags, bit); +} + void fastcall wait_on_page_bit(struct page *page, int bit_nr) { -wait_queue_head_t *waitqueue =page_waitqueue (page);DEFINE_WAIT_BIT (wait, &page->flags, bit_nr); -prepare_to_wait (waitqueue, &wait.wait,TASK_UNINTERRUPTIBLE ); -if (test_bit (bit_nr, &page->flags)) { -sync_page (page); -io_schedule (); - } -finish_wait (waitqueue, &wait.wait); +if (test_bit (bit_nr, &page->flags)) +__wait_on_bit (page_waitqueue (page), &wait, wait.key.flags, + bit_nr, sync_page,TASK_UNINTERRUPTIBLE ); } -EXPORT_SYMBOL (wait_on_page_bit);/**
@@ -398,7 +401,7 @@if (!TestClearPageLocked (page))BUG ();smp_mb__after_clear_bit (); -__wake_up_bit (page_waitqueue (page), &page->flags, PG_locked); +wake_up_page (page, PG_locked); }EXPORT_SYMBOL (unlock_page);
@@ -414,7 +417,7 @@BUG ();smp_mb__after_clear_bit (); } -__wake_up_bit (page_waitqueue (page), &page->flags, PG_writeback); +wake_up_page (page, PG_writeback); }EXPORT_SYMBOL (end_page_writeback);
@@ -429,19 +432,11 @@*/ void fastcall __lock_page(struct page *page) { -wait_queue_head_t *wqh =page_waitqueue (page);DEFINE_WAIT_BIT (wait, &page->flags, PG_locked); -while (TestSetPageLocked (page)) { -prepare_to_wait_exclusive (wqh, &wait.wait,TASK_UNINTERRUPTIBLE ); -if (PageLocked (page)) { -sync_page (page); -io_schedule (); - } - } -finish_wait (wqh, &wait.wait); +__wait_on_bit_lock (page_waitqueue (page), &wait, wait.key.flags, + PG_locked, sync_page,TASK_UNINTERRUPTIBLE ); } -EXPORT_SYMBOL (__lock_page);/*
include/linux/wait.h +2 -0
@@ -139,6 +139,8 @@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));void FASTCALL (__wake_up_bit (wait_queue_head_t *,void *,int )); +int FASTCALL (__wait_on_bit (wait_queue_head_t *,struct wait_bit_queue *,void *,int ,int (*)(void *),unsigned )); +int FASTCALL (__wait_on_bit_lock (wait_queue_head_t *,struct wait_bit_queue *,void *,int ,int (*)(void *),unsigned ));#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, NULL)
PATCH 4/5 eliminate bh waitqueue hashtable
Quoted 2 lines · William Lee Irwin III
Consolidate bit waiting code patterns for page waitqueues using
__wait_on_bit()and__wait_on_bit_lock().
Eliminate the bh waitqueue hashtable using bit_waitqueue() via wait_on_bit() and wake_up_bit() to locate the waitqueue head associated with a bit.
fs/buffer.c +9 -46
@@ -43,14 +43,6 @@#define BH_ENTRY (list) list_entry((list), struct buffer_head, b_assoc_buffers) -/* -* Hashed waitqueue_head's for wait_on_buffer() -*/ -#define BH_WAIT_TABLE_ORDER 7 -static struct bh_wait_queue_head { -wait_queue_head_t wqh; -}____cacheline_aligned_in_smp bh_wait_queue_heads[1 <<BH_WAIT_TABLE_ORDER ]; -inline void init_buffer (struct buffer_head *bh,bh_end_io_t *handler,void *private) {
@@ -58,49 +50,31 @@ bh->b_private = private; } -/* -* Return the address of the waitqueue_head to be used for this -* buffer_head -*/ -wait_queue_head_t *bh_waitq_head (struct buffer_head *bh) -{ -return &bh_wait_queue_heads[hash_ptr (bh,BH_WAIT_TABLE_ORDER )].wqh; -} -EXPORT_SYMBOL (bh_waitq_head); -void wake_up_buffer (struct buffer_head *bh) { -wait_queue_head_t *wq =bh_waitq_head (bh); -smp_mb (); -__wake_up_bit (wq, &bh->b_state, BH_Lock); +wake_up_bit (&bh->b_state, BH_Lock); }EXPORT_SYMBOL (wake_up_buffer); -static void sync_buffer (struct buffer_head *bh) +static int sync_buffer (void *word) {struct block_device *bd; +struct buffer_head *bh + = container_of(word, struct buffer_head, b_state);smp_mb (); bd = bh->b_bdev;if (bd)blk_run_address_space (bd->bd_inode->i_mapping); +io_schedule (); +return 0 ; } void fastcall __lock_buffer(struct buffer_head *bh) { -wait_queue_head_t *wqh =bh_waitq_head (bh); -DEFINE_WAIT_BIT (wait, &bh->b_state, BH_Lock); - -do { -prepare_to_wait_exclusive (wqh, &wait.wait, -TASK_UNINTERRUPTIBLE ); -if (buffer_locked (bh)) { -sync_buffer (bh); -io_schedule (); - } - }while (test_set_buffer_locked (bh)); -finish_wait (wqh, &wait.wait); +wait_on_bit_lock (&bh->b_state, BH_Lock, sync_buffer, +TASK_UNINTERRUPTIBLE ); }EXPORT_SYMBOL (__lock_buffer);
@@ -118,15 +92,7 @@*/ void __wait_on_buffer (struct buffer_head * bh) { -wait_queue_head_t *wqh =bh_waitq_head (bh); -DEFINE_WAIT_BIT (wait, &bh->b_state, BH_Lock); - -prepare_to_wait (wqh, &wait.wait,TASK_UNINTERRUPTIBLE ); -if (buffer_locked (bh)) { -sync_buffer (bh); -io_schedule (); - } -finish_wait (wqh, &wait.wait); +wait_on_bit (&bh->b_state, BH_Lock, sync_buffer,TASK_UNINTERRUPTIBLE ); } static void
@@ -3096,14 +3062,11 @@void __init buffer_init (void ) { -int i;int nrpages; bh_cachep =kmem_cache_create ("buffer_head" ,sizeof (struct buffer_head ),0 ,SLAB_PANIC , init_buffer_head,NULL ); -for (i =0 ; i <ARRAY_SIZE (bh_wait_queue_heads); i++) -init_waitqueue_head (&bh_wait_queue_heads[i].wqh);/* * Limit the bh occupancy to 10% of ZONE_NORMAL
kernel/wait.c +11 -0
@@ -8,6 +8,7 @@#include <linux/module.h> #include <linux/sched.h> #include <linux/wait.h> +#include <linux/hash.h> void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) {
@@ -187,3 +188,13 @@__wake_up (wq,TASK_INTERRUPTIBLE |TASK_UNINTERRUPTIBLE ,1 , &key); }EXPORT_SYMBOL (__wake_up_bit); + +wait_queue_head_t * fastcall bit_waitqueue(void *word, int bit) +{ +const int shift =BITS_PER_LONG ==32 ?5 :6 ; +const struct zone *zone =page_zone (virt_to_page (word)); +unsigned long val = (unsigned long )word << shift | bit; + +return &zone->wait_table[hash_long (val, zone->wait_table_bits)]; +} +EXPORT_SYMBOL (bit_waitqueue);
fs/jbd/transaction.c +5 -5
@@ -633,21 +633,21 @@* disk then we cannot do copy-out here. */ if (jh->b_jlist == BJ_Shadow) { -wait_queue_head_t *wqh; -DEFINE_WAIT (wait); +DEFINE_WAIT_BIT (wait, &bh->b_state, BH_Lock); +wait_queue_head_t *wqh + =bit_waitqueue (&bh->b_state, BH_Lock);JBUFFER_TRACE (jh,"on shadow: sleep" );jbd_unlock_bh_state (bh);/* commit wakes up all shadow buffers after IO */ - wqh =bh_waitq_head (bh);for ( ; ; ) { -prepare_to_wait (wqh, &wait, +prepare_to_wait (wqh, &wait.wait,TASK_UNINTERRUPTIBLE );if (jh->b_jlist != BJ_Shadow)break ;schedule (); } -finish_wait (wqh, &wait); +finish_wait (wqh, &wait.wait); goto repeat; }
include/linux/wait.h +73 -0
91 lines not on this page · raw message
PATCH 5/5 eliminate inode waitqueue hashtable
Quoted 3 lines · William Lee Irwin III
Eliminate the bh waitqueue hashtable using
bit_waitqueue()viawait_on_bit()andwake_up_bit()to locate the waitqueue head associated with a bit.
Eliminate the inode waitqueue hashtable using bit_waitqueue() via wait_on_bit() and wake_up_bit() to locate the waitqueue head associated with a bit.
include/linux/fs.h +1 -0
@@ -1057,6 +1057,7 @@#define I_NEW 64#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES) +#define __I_LOCK 3/* I_LOCK == 1 << __I_LOCK */ extern void __mark_inode_dirty (struct inode *,int );static inline void mark_inode_dirty (struct inode *inode)
fs/inode.c +20 -49
104 lines not on this page · raw message
kernel/wait.c +1 -0
@@ -7,6 +7,7 @@#include <linux/init.h> #include <linux/module.h> #include <linux/sched.h> +#include <linux/mm.h> #include <linux/wait.h> #include <linux/hash.h>
fs/fs-writeback.c +14 -6
@@ -240,6 +240,8 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc) { + wait_queue_head_t *wqh; +if ((wbc->sync_mode !=WB_SYNC_ALL ) && (inode->i_state &I_LOCK )) {list_move (&inode->i_list, &inode->i_sb->s_dirty);return 0 ;
@@ -248,12 +250,18 @@/* * It's a data-integrity sync. We must wait. */ -while (inode->i_state &I_LOCK ) { -__iget (inode); -spin_unlock (&inode_lock); -__wait_on_inode (inode); -iput (inode); -spin_lock (&inode_lock); +if (inode->i_state &I_LOCK ) { +DEFINE_WAIT_BIT (wq, &inode->i_state, __I_LOCK); + + wqh =bit_waitqueue (&inode->i_state, __I_LOCK); +do { +__iget (inode); +spin_unlock (&inode_lock); +__wait_on_bit (wqh, &wq, &inode->i_state, __I_LOCK, + inode_wait,TASK_UNINTERRUPTIBLE ); +iput (inode); +spin_lock (&inode_lock); + }while (inode->i_state &I_LOCK ); }return __sync_single_inode (inode, wbc); }
include/linux/writeback.h +3 -3
@@ -68,7 +68,7 @@*/ void writeback_inodes (struct writeback_control *wbc);void wake_up_inode (struct inode *inode); -void __wait_on_inode (struct inode * inode); +int inode_wait (void *);void sync_inodes_sb (struct super_block *,int wait);void sync_inodes (int wait);
@@ -76,8 +76,8 @@static inline void wait_on_inode (struct inode *inode) {might_sleep (); -if (inode->i_state &I_LOCK ) -__wait_on_inode (inode); +wait_on_bit (&inode->i_state, __I_LOCK, inode_wait, +TASK_UNINTERRUPTIBLE ); }/*
Re: [4/5] eliminate bh waitqueue hashtable
In reply to William Lee Irwin IIIQuoted 13 lines · William Lee Irwin III
+static inline int wait_on_bit(void *word, int bit,
+ int (*action)(void *), unsigned mode)
+{
+DEFINE_WAIT_BIT(q, word, bit);
+wait_queue_head_t*wqh;
+
+ if (!test_bit(bit, word))
+ return 0;
+
+ wqh =bit_waitqueue(word, bit);
+ return__wait_on_bit(wqh, &q, word, bit, action, mode);
+}
This is still all inlined. Given that we're going to schedule away, don't you think we should out-of-line the slowpath? As I said yesterday:
static inline int wait_on_bit(...)
{
if (test_bit(...))
return out_of_line_wait_on_bit(...);
return 0;
}I merged this latest batch into -mm.
Re: [4/5] eliminate bh waitqueue hashtable
Quoted 9 lines · Andrew Morton
This is still all inlined. Given that we're going to schedule away, don't you think we should out-of-line the slowpath? As I said yesterday:
static inline intwait_on_bit(...){ if (test_bit(...)) return out_of_line_wait_on_bit(...); return 0; }I merged this latest batch into -mm.
Neither bit_waitqueue() nor __wait_on_bit() are inlined, but it is possible to reduce things to only one call site. I'll send in that update if you've not done it yourself after I get a chance to see what's been merged.
-- wli
Re: [2/5] consolidate bit waiting code patterns
In reply to William Lee Irwin IIIfs/buffer.c line 44
Quoted 11 lines · William Lee Irwin III
Eliminate specialized page and bh waitqueue hashing structures in favor of a standardized structure, using
wake_up_bit()to wake waiters using the standardizedwait_bit_keystructure.Index:
wait-2.6.9-rc1-mm1/fs/buffer.c
===================================================================fs/buffer.c +0
-0@@ -43,26 +43,6 @@#define BH_ENTRY (list) list_entry((list), struct buffer_head, b_assoc_buffers)
Sorry, the Subject: line should have been titled "standardize bit waiting data type".
-- wli
Re: [2/5] consolidate bit waiting code patterns
In reply to William Lee Irwin IIIQuoted 7 lines · William Lee Irwin III
+void fastcall
__wake_up_bit(wait_queue_head_t *wq, void *word, int bit)
+{
+ structwait_bit_keykey =__WAIT_BIT_KEY_INITIALIZER(word, bit);
+ if (waitqueue_active(wq))
+__wake_up(wq, TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE, 1, &key);
+}
The waitqueue_active() test needs a preceding barrier. Did it come from somewhere else, implicitly?
Re: [2/5] consolidate bit waiting code patterns
Quoted 6 lines · William Lee Irwin III
Quoted 6 lines
+void fastcall
__wake_up_bit(wait_queue_head_t *wq, void *word, int bit)
+{
+ structwait_bit_keykey =__WAIT_BIT_KEY_INITIALIZER(word, bit);
+ if (waitqueue_active(wq))
+__wake_up(wq, TASK_INTERRUPTIBLE|TASK_UNINTERRUPTIBLE, 1, &key);
+}
Quoted 2 lines · Andrew Morton
The
waitqueue_active()test needs a preceding barrier. Did it come from somewhere else, implicitly?
Yes, it comes from clearing the bit prior to calling this for wakeup.
-- wli