From: William Lee Irwin III <wli@holomorphy.com>
To: Andrew Morton <akpm@osdl.org>
Cc: oleg@tv-sign.ru, linux-kernel@vger.kernel.org
Subject: [3/4] eliminate bh waitqueue hashtable
Date: Sat, 28 Aug 2004 02:23:37 -0700 [thread overview]
Message-ID: <20040828092337.GK5492@holomorphy.com> (raw)
In-Reply-To: <20040828092210.GJ5492@holomorphy.com>
On Sat, Aug 28, 2004 at 02:22:10AM -0700, William Lee Irwin III wrote:
> 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.
Index: mm1-2.6.9-rc1/fs/buffer.c
===================================================================
--- mm1-2.6.9-rc1.orig/fs/buffer.c 2004-08-27 23:50:07.644312184 -0700
+++ mm1-2.6.9-rc1/fs/buffer.c 2004-08-28 01:23:05.396364984 -0700
@@ -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
Index: mm1-2.6.9-rc1/fs/jbd/transaction.c
===================================================================
--- mm1-2.6.9-rc1.orig/fs/jbd/transaction.c 2004-08-26 15:03:31.000000000 -0700
+++ mm1-2.6.9-rc1/fs/jbd/transaction.c 2004-08-28 01:23:05.404363768 -0700
@@ -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;
}
Index: mm1-2.6.9-rc1/kernel/fork.c
===================================================================
--- mm1-2.6.9-rc1.orig/kernel/fork.c 2004-08-28 01:23:00.542102944 -0700
+++ mm1-2.6.9-rc1/kernel/fork.c 2004-08-28 01:23:05.410362856 -0700
@@ -40,6 +40,7 @@
#include <linux/audit.h>
#include <linux/profile.h>
#include <linux/rmap.h>
+#include <linux/hash.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -242,6 +243,16 @@
}
EXPORT_SYMBOL(wake_bit_function);
+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);
+
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);
Index: mm1-2.6.9-rc1/include/linux/wait.h
===================================================================
--- mm1-2.6.9-rc1.orig/include/linux/wait.h 2004-08-28 01:23:00.554101120 -0700
+++ mm1-2.6.9-rc1/include/linux/wait.h 2004-08-28 01:44:13.448591744 -0700
@@ -24,6 +24,7 @@
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <asm/system.h>
+#include <asm/current.h>
typedef struct __wait_queue wait_queue_t;
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key);
@@ -141,6 +142,22 @@
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));
+wait_queue_head_t *FASTCALL(bit_waitqueue(void *, int));
+
+/**
+ * wake_up_bit - wake up a waiter on a bit
+ * @word: the word being waited on, a kernel virtual address
+ * @bit: the bit of the word being waited on
+ *
+ * There is a standard hashed waitqueue table for generic use. This
+ * is the part of the hashtable's accessor API that wakes up waiters
+ * on a bit. For instance, if one were to have waiters on a bitflag,
+ * one would call wake_up_bit() after clearing the bit.
+ */
+static inline void wake_up_bit(void *word, int bit)
+{
+ __wake_up_bit(bit_waitqueue(word, bit), word, bit);
+}
#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)
@@ -321,6 +338,54 @@
wait->func = autoremove_wake_function; \
INIT_LIST_HEAD(&wait->task_list); \
} while (0)
+
+/**
+ * wait_on_bit - wait for a bit to be cleared
+ * @word: the word being waited on, a kernel virtual address
+ * @bit: the bit of the word being waited on
+ * @wait: the function used to sleep, which may take special actions
+ * @mode: the task state to sleep in
+ *
+ * There is a standard hashed waitqueue table for generic use. This
+ * is the part of the hashtable's accessor API that waits on a bit.
+ * For instance, if one were to have waiters on a bitflag, one would
+ * call wait_on_bit() in threads waiting for the bit to clear.
+ * One uses wait_on_bit() where one is waiting for the bit to clear,
+ * but has no intention of setting it.
+ */
+static inline int wait_on_bit(void *word, int bit,
+ int (*wait)(void *), unsigned mode)
+{
+ DEFINE_WAIT_BIT(q, word, bit);
+ wait_queue_head_t *wqh = bit_waitqueue(word, bit);
+
+ return __wait_on_bit(wqh, &q, word, bit, wait, mode);
+}
+
+/**
+ * wait_on_bit_lock - wait for a bit to be cleared, when wanting to set it
+ * @word: the word being waited on, a kernel virtual address
+ * @bit: the bit of the word being waited on
+ * @wait: the function used to sleep, which may take special actions
+ * @mode: the task state to sleep in
+ *
+ * There is a standard hashed waitqueue table for generic use. This
+ * is the part of the hashtable's accessor API that waits on a bit
+ * when one intends to set it, for instance, trying to lock bitflags.
+ * For instance, if one were to have waiters trying to set bitflag
+ * and waiting for it to clear before setting it, one would call
+ * wait_on_bit() in threads waiting to be able to set the bit.
+ * One uses wait_on_bit_lock() where one is waiting for the bit to
+ * clear with the intention of setting it, and when done, clearing it.
+ */
+static inline int wait_on_bit_lock(void *word, int bit,
+ int (*wait)(void *), unsigned mode)
+{
+ DEFINE_WAIT_BIT(q, word, bit);
+ wait_queue_head_t *wqh = bit_waitqueue(word, bit);
+
+ return __wait_on_bit_lock(wqh, &q, word, bit, wait, mode);
+}
#endif /* __KERNEL__ */
next prev parent reply other threads:[~2004-08-28 9:25 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-08-26 8:47 2.6.9-rc1-mm1 Andrew Morton
2004-08-26 11:07 ` 2.6.9-rc1-mm1 Con Kolivas
2004-08-26 14:28 ` 2.6.9-rc1-mm1 Jurriaan
2004-08-26 18:25 ` 2.6.9-rc1-mm1 Thomas Davis
2004-08-26 14:36 ` 2.6.9-rc1-mm1 Rafael J. Wysocki
2004-08-26 14:45 ` 2.6.9-rc1-mm1 Felipe Alfaro Solana
2004-08-26 15:35 ` 2.6.9-rc1-mm1 Rafael J. Wysocki
2004-08-26 16:38 ` 2.6.9-rc1-mm1 Con Kolivas
2004-08-26 20:36 ` 2.6.9-rc1-mm1 Rafael J. Wysocki
2004-08-26 20:55 ` 2.6.9-rc1-mm1 Martin J. Bligh
2004-08-26 23:19 ` 2.6.9-rc1-mm1 Con Kolivas
2004-08-26 23:43 ` 2.6.9-rc1-mm1 Martin J. Bligh
2004-08-27 0:37 ` 2.6.9-rc1-mm1 Nuno Silva
2004-08-27 0:46 ` 2.6.9-rc1-mm1 Con Kolivas
2004-08-27 0:51 ` 2.6.9-rc1-mm1 Martin J. Bligh
2004-08-27 0:55 ` 2.6.9-rc1-mm1 Con Kolivas
2004-08-27 0:58 ` 2.6.9-rc1-mm1 Rick Lindsley
2004-08-27 20:54 ` 2.6.9-rc1-mm1 Rafael J. Wysocki
2004-08-27 21:54 ` 2.6.9-rc1-mm1 Rick Lindsley
2004-08-27 22:29 ` 2.6.9-rc1-mm1 Rafael J. Wysocki
2004-09-03 21:11 ` schedstat-2.6.8.1 [was: Re: 2.6.9-rc1-mm1] Rafael J. Wysocki
2004-09-08 7:09 ` Rick Lindsley
2004-09-04 18:35 ` 2.6.9-rc1-mm1 Rafael J. Wysocki
2004-09-08 8:10 ` 2.6.9-rc1-mm1 Rick Lindsley
2004-09-04 23:10 ` latency.c [was: Re: 2.6.9-rc1-mm1] Rafael J. Wysocki
2004-09-08 8:12 ` Rick Lindsley
2004-09-08 12:02 ` Rafael J. Wysocki
2004-08-26 20:51 ` 2.6.9-rc1-mm1 Martin J. Bligh
2004-08-27 1:43 ` 2.6.9-rc1-mm1 Nick Piggin
2004-08-26 12:06 ` 2.6.9-rc1-mm1 Denis Vlasenko
2004-08-26 19:40 ` 2.6.9-rc1-mm1 Sam Ravnborg
2004-08-26 17:58 ` 2.6.9-rc1-mm1 (compile stats) John Cherry
2004-08-26 18:53 ` 2.6.9-rc1-mm1 - undefined references - [PATCH] Paolo Ornati
2004-08-28 8:54 ` Adrian Bunk
2004-08-28 9:45 ` Paolo Ornati
2004-08-26 22:46 ` 2.6.9-rc1-mm1 Rafael J. Wysocki
2004-08-26 22:50 ` 2.6.9-rc1-mm1 Andrew Morton
2004-08-26 23:53 ` 2.6.9-rc1-mm1 Tomasz Torcz
[not found] ` <20040827043132.GJ2793@holomorphy.com>
2004-08-27 21:42 ` 2.6.9-rc1-mm1 William Lee Irwin III
2004-08-28 5:26 ` [0/4] standardized waitqueue hashing William Lee Irwin III
2004-08-28 5:31 ` [1/4] standardize bit waiting data type William Lee Irwin III
2004-08-28 5:35 ` [2/4] consolidate bit waiting code patterns William Lee Irwin III
2004-08-28 5:37 ` [3/4] eliminate bh waitqueue hashtable William Lee Irwin III
2004-08-28 5:38 ` [4/4] eliminate inode " William Lee Irwin III
2004-08-28 6:17 ` [1/4] standardize bit waiting data type Andrew Morton
2004-08-28 6:34 ` William Lee Irwin III
2004-08-28 6:40 ` Andrew Morton
2004-08-28 6:48 ` William Lee Irwin III
2004-08-28 9:20 ` William Lee Irwin III
2004-08-28 9:22 ` [2/4] consolidate bit waiting code patterns William Lee Irwin III
2004-08-28 9:23 ` William Lee Irwin III [this message]
2004-08-28 9:24 ` [4/4] eliminate inode waitqueue hashtable William Lee Irwin III
2004-08-28 9:43 ` [3/4] eliminate bh " Andrew Morton
2004-08-28 9:34 ` [2/4] consolidate bit waiting code patterns Andrew Morton
2004-08-28 9:51 ` William Lee Irwin III
2004-08-28 9:39 ` Andrew Morton
2004-08-28 9:51 ` William Lee Irwin III
2004-08-28 9:18 ` [1/4] standardize bit waiting data type Christoph Hellwig
2004-08-28 9:20 ` William Lee Irwin III
2004-08-28 9:06 ` [patch] 2.6.9-rc1-mm1: megaraid_mbox.c compile error with gcc 3.4 Adrian Bunk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040828092337.GK5492@holomorphy.com \
--to=wli@holomorphy.com \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=oleg@tv-sign.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox