From: Hubertus Franke <frankeh@watson.ibm.com>
To: Rusty Russell <rusty@rustcorp.com.au>
Cc: torvalds@transmeta.com, linux-kernel@vger.kernel.org,
lse-tech@lists.sourceforge.net
Subject: Futexes V :
Date: Wed, 6 Mar 2002 15:36:25 -0500 [thread overview]
Message-ID: <20020306203522.4994A3FE06@smtp.linux.ibm.com> (raw)
In-Reply-To: <E16i8x2-0008TV-00@wagner.rustcorp.com.au> <20020306185420.29df1bf2.rusty@rustcorp.com.au> <20020306161229.0821D3FE06@smtp.linux.ibm.com>
In-Reply-To: <20020306161229.0821D3FE06@smtp.linux.ibm.com>
On Wednesday 06 March 2002 11:13 am, Hubertus Franke wrote:
I cut a new version with what I was previously discussing.
Now we have two kind of wakeup mechanism
(a) regular wakeup (as was) which basically gives you convoy avoidance
(b) fair wakeup (will first wake a waiting process up .. FIFO)
Basically integrated 2 prior patches of Rusty
Also changed FUTEX_DOWN, FUTEX_UP and FUTEX_UP_FAIR
operands to be linear (0,1,2), should make the case statement faster,
particularly when we get more operands.
frankeh:1019:~/futex/ulockflex>
./ulockflex -c 3 -a 1 -t 2 -o 5 -m 2 -R 499 -r 0 -x 0 -L f
SysV: 3 1 2 1 k 0 0 0 99.42 0.00 0.00 0.141423 243718
FAIR: 3 1 2 1 f 0 0 0 93.67 0.00 0.00 0.049231 217001
CA: 3 1 2 1 f 0 0 0 0.01 0.00 0.00 0.154154 2002852
Yesterdays numbers where
3 1 5 4 k 0 0 0 99.98 0.00 0.00 0.033284 242040
3 1 5 4 m 0 0 0 0.29 0.00 0.00 0.018406 1979992
3 1 5 4 f 0 0 0 99.71 0.00 0.00 0.028083 306140
3 1 5 4 c 0 0 0 7.79 0.00 4.00 0.437084 774175
Indicates that fair locking still needs some work, but what Rusty provided
on top the current
--
-- Hubertus Franke (frankeh@watson.ibm.com)
---------------------------------------------------------------------------------------------
diff -urbN linux-2.5.5/arch/i386/kernel/entry.S
linux-2.5.5-futex/arch/i386/kernel/entry.S
--- linux-2.5.5/arch/i386/kernel/entry.S Tue Feb 19 21:10:58 2002
+++ linux-2.5.5-futex/arch/i386/kernel/entry.S Wed Mar 6 11:40:12 2002
@@ -716,6 +716,7 @@
.long SYMBOL_NAME(sys_lremovexattr)
.long SYMBOL_NAME(sys_fremovexattr)
.long SYMBOL_NAME(sys_tkill)
+ .long SYMBOL_NAME(sys_futex)
.rept NR_syscalls-(.-sys_call_table)/4
.long SYMBOL_NAME(sys_ni_syscall)
diff -urbN linux-2.5.5/arch/ppc/kernel/misc.S
linux-2.5.5-futex/arch/ppc/kernel/misc.S
--- linux-2.5.5/arch/ppc/kernel/misc.S Tue Feb 19 21:11:00 2002
+++ linux-2.5.5-futex/arch/ppc/kernel/misc.S Wed Mar 6 11:40:12 2002
@@ -1246,6 +1246,7 @@
.long sys_removexattr
.long sys_lremovexattr
.long sys_fremovexattr /* 220 */
+ .long sys_futex
.rept NR_syscalls-(.-sys_call_table)/4
.long sys_ni_syscall
.endr
diff -urbN linux-2.5.5/include/asm-i386/atomic.h
linux-2.5.5-futex/include/asm-i386/atomic.h
--- linux-2.5.5/include/asm-i386/atomic.h Tue Feb 19 21:10:58 2002
+++ linux-2.5.5-futex/include/asm-i386/atomic.h Wed Mar 6 11:42:35 2002
@@ -2,6 +2,7 @@
#define __ARCH_I386_ATOMIC__
#include <linux/config.h>
+#include <asm/system.h>
/*
* Atomic operations that C can't guarantee us. Useful for
diff -urbN linux-2.5.5/include/asm-i386/mman.h
linux-2.5.5-futex/include/asm-i386/mman.h
--- linux-2.5.5/include/asm-i386/mman.h Tue Feb 19 21:10:56 2002
+++ linux-2.5.5-futex/include/asm-i386/mman.h Wed Mar 6 11:40:12 2002
@@ -4,6 +4,7 @@
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
+#define PROT_SEM 0x8 /* page may be used for atomic ops */
#define PROT_NONE 0x0 /* page can not be accessed */
#define MAP_SHARED 0x01 /* Share changes */
diff -urbN linux-2.5.5/include/asm-i386/unistd.h
linux-2.5.5-futex/include/asm-i386/unistd.h
--- linux-2.5.5/include/asm-i386/unistd.h Tue Feb 19 21:11:04 2002
+++ linux-2.5.5-futex/include/asm-i386/unistd.h Wed Mar 6 11:40:12 2002
@@ -243,6 +243,7 @@
#define __NR_lremovexattr 236
#define __NR_fremovexattr 237
#define __NR_tkill 238
+#define __NR_futex 239
/* user-visible error numbers are in the range -1 - -124: see
<asm-i386/errno.h> */
diff -urbN linux-2.5.5/include/asm-ppc/mman.h
linux-2.5.5-futex/include/asm-ppc/mman.h
--- linux-2.5.5/include/asm-ppc/mman.h Tue Feb 19 21:11:03 2002
+++ linux-2.5.5-futex/include/asm-ppc/mman.h Wed Mar 6 11:40:12 2002
@@ -7,6 +7,7 @@
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
+#define PROT_SEM 0x8 /* page may be used for atomic ops */
#define PROT_NONE 0x0 /* page can not be accessed */
#define MAP_SHARED 0x01 /* Share changes */
diff -urbN linux-2.5.5/include/asm-ppc/unistd.h
linux-2.5.5-futex/include/asm-ppc/unistd.h
--- linux-2.5.5/include/asm-ppc/unistd.h Tue Feb 19 21:10:57 2002
+++ linux-2.5.5-futex/include/asm-ppc/unistd.h Wed Mar 6 11:40:12 2002
@@ -228,6 +228,7 @@
#define __NR_removexattr 218
#define __NR_lremovexattr 219
#define __NR_fremovexattr 220
+#define __NR_futex 221
#define __NR(n) #n
diff -urbN linux-2.5.5/include/linux/futex.h
linux-2.5.5-futex/include/linux/futex.h
--- linux-2.5.5/include/linux/futex.h Wed Dec 31 19:00:00 1969
+++ linux-2.5.5-futex/include/linux/futex.h Wed Mar 6 13:58:21 2002
@@ -0,0 +1,9 @@
+#ifndef _LINUX_FUTEX_H
+#define _LINUX_FUTEX_H
+
+/* Second argument to futex syscall */
+#define FUTEX_DOWN (0)
+#define FUTEX_UP (1)
+#define FUTEX_UP_FAIR (2)
+
+#endif
diff -urbN linux-2.5.5/include/linux/hash.h
linux-2.5.5-futex/include/linux/hash.h
--- linux-2.5.5/include/linux/hash.h Wed Dec 31 19:00:00 1969
+++ linux-2.5.5-futex/include/linux/hash.h Wed Mar 6 11:40:12 2002
@@ -0,0 +1,58 @@
+#ifndef _LINUX_HASH_H
+#define _LINUX_HASH_H
+/* Fast hashing routine for a long.
+ (C) 2002 William Lee Irwin III, IBM */
+
+/*
+ * Knuth recommends primes in approximately golden ratio to the maximum
+ * integer representable by a machine word for multiplicative hashing.
+ * Chuck Lever verified the effectiveness of this technique:
+ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
+ *
+ * These primes are chosen to be bit-sparse, that is operations on
+ * them can use shifts and additions instead of multiplications for
+ * machines where multiplications are slow.
+ */
+#if BITS_PER_LONG == 32
+/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e370001UL
+#elif BITS_PER_LONG == 64
+/* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL
+#else
+#error Define GOLDEN_RATIO_PRIME for your wordsize.
+#endif
+
+static inline unsigned long hash_long(unsigned long val, unsigned int bits)
+{
+ unsigned long hash = val;
+
+#if BITS_PER_LONG == 64
+ /* Sigh, gcc can't optimise this alone like it does for 32 bits. */
+ unsigned long n = hash;
+ n <<= 18;
+ hash -= n;
+ n <<= 33;
+ hash -= n;
+ n <<= 3;
+ hash += n;
+ n <<= 3;
+ hash -= n;
+ n <<= 4;
+ hash += n;
+ n <<= 2;
+ hash += n;
+#else
+ /* On some cpus multiply is faster, on others gcc will do shifts */
+ hash *= GOLDEN_RATIO_PRIME;
+#endif
+
+ /* High bits are more random, so use them. */
+ return hash >> (BITS_PER_LONG - bits);
+}
+
+static inline unsigned long hash_ptr(void *ptr, unsigned int bits)
+{
+ return hash_long((unsigned long)ptr, bits);
+}
+#endif /* _LINUX_HASH_H */
diff -urbN linux-2.5.5/include/linux/mmzone.h
linux-2.5.5-futex/include/linux/mmzone.h
--- linux-2.5.5/include/linux/mmzone.h Tue Feb 19 21:10:53 2002
+++ linux-2.5.5-futex/include/linux/mmzone.h Wed Mar 6 11:42:35 2002
@@ -51,8 +51,7 @@
/*
* wait_table -- the array holding the hash table
* wait_table_size -- the size of the hash table array
- * wait_table_shift -- wait_table_size
- * == BITS_PER_LONG (1 << wait_table_bits)
+ * wait_table_bits -- wait_table_size == (1 << wait_table_bits)
*
* The purpose of all these is to keep track of the people
* waiting for a page to become available and make them
@@ -75,7 +74,7 @@
*/
wait_queue_head_t * wait_table;
unsigned long wait_table_size;
- unsigned long wait_table_shift;
+ unsigned long wait_table_bits;
/*
* Discontig memory support fields.
diff -urbN linux-2.5.5/kernel/Makefile linux-2.5.5-futex/kernel/Makefile
--- linux-2.5.5/kernel/Makefile Tue Feb 19 21:10:57 2002
+++ linux-2.5.5-futex/kernel/Makefile Wed Mar 6 11:40:12 2002
@@ -15,7 +15,7 @@
obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
module.o exit.o itimer.o info.o time.o softirq.o resource.o \
sysctl.o acct.o capability.o ptrace.o timer.o user.o \
- signal.o sys.o kmod.o context.o
+ signal.o sys.o kmod.o context.o futex.o
obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += ksyms.o
diff -urbN linux-2.5.5/kernel/futex.c linux-2.5.5-futex/kernel/futex.c
--- linux-2.5.5/kernel/futex.c Wed Dec 31 19:00:00 1969
+++ linux-2.5.5-futex/kernel/futex.c Wed Mar 6 13:59:01 2002
@@ -0,0 +1,255 @@
+/*
+ * Fast Userspace Mutexes (which I call "Futexes!").
+ * (C) Rusty Russell, IBM 2002
+ *
+ * Thanks to Ben LaHaise for yelling "hashed waitqueues" loudly
+ * enough at me, Linus for the original (flawed) idea, Matthew
+ * Kirkwood for proof-of-concept implementation.
+ *
+ * "The futexes are also cursed."
+ * "But they come in a choice of three flavours!"
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/hash.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/futex.h>
+#include <asm/atomic.h>
+
+/* These mutexes are a very simple counter: the winner is the one who
+ decrements from 1 to 0. 1 == free. 0 == noone sleeping.
+
+ This is simple enough to work on all architectures. */
+
+/* FIXME: This may be way too small. --RR */
+#define FUTEX_HASHBITS 6
+
+/* We use this instead of a wait_queue_t, so we can wake only the
+ relevent ones (hashed queues may be shared) */
+struct futex_q {
+ struct list_head list;
+ struct task_struct *task;
+ atomic_t *count;
+};
+
+/* The key for the hash is the address + offset within page */
+static struct list_head futex_queues[1<<FUTEX_HASHBITS];
+static spinlock_t futex_lock = SPIN_LOCK_UNLOCKED;
+
+#define FUTEX_PASSED ((void *)-1)
+
+/* Try to find someone else to pass futex to. */
+static int pass_futex(struct list_head *head, atomic_t *count)
+{
+ struct list_head *i;
+ struct futex_q *recipient = NULL;
+ int more_candidates = 0;
+
+ /* Find first, and keep looking to see if there are others. */
+ list_for_each(i, head) {
+ struct futex_q *this = list_entry(i, struct futex_q, list);
+
+ if (this->count == count) {
+ if (!recipient) recipient = this;
+ else {
+ /* Someone else waiting, too. */
+ more_candidates = 1;
+ break;
+ }
+ }
+ }
+
+ /* Nobody wants it. */
+ if (!recipient)
+ return 0;
+
+ /* Fixup to avoid wasted wakeup when we up() later. */
+ if (!more_candidates)
+ atomic_set(count, 0);
+
+ /* Pass directly to them. */
+ recipient->count = FUTEX_PASSED;
+ smp_wmb();
+ wake_up_process(recipient->task);
+ return 1;
+}
+
+static inline void wake_one_waiter(struct list_head *head, atomic_t *count)
+{
+ struct list_head *i;
+
+ spin_lock(&futex_lock);
+ list_for_each(i, head) {
+ struct futex_q *this = list_entry(i, struct futex_q, list);
+
+ if (this->count == count) {
+ wake_up_process(this->task);
+ break;
+ }
+ }
+ spin_unlock(&futex_lock);
+}
+
+static inline struct list_head *hash_futex(struct page *page,
+ unsigned long offset)
+{
+ unsigned long h;
+
+ /* If someone is sleeping, page is pinned. ie. page_address
+ is a constant when we care about it. */
+ h = (unsigned long)page_address(page) + offset;
+ return &futex_queues[hash_long(h, FUTEX_HASHBITS)];
+}
+
+/* Add at end to make it FIFO. */
+static inline void queue_me(struct list_head *head, struct futex_q *q)
+{
+ q->task = current;
+
+ spin_lock(&futex_lock);
+ list_add_tail(&q->list, head);
+ spin_unlock(&futex_lock);
+}
+
+/* Return true if there is someone else waiting as well */
+static inline void unqueue_me(struct futex_q *q)
+{
+ spin_lock(&futex_lock);
+ list_del(&q->list);
+ spin_unlock(&futex_lock);
+}
+
+/* Get kernel address of the user page and pin it. */
+static struct page *pin_page(unsigned long page_start)
+{
+ struct mm_struct *mm = current->mm;
+ struct page *page;
+ int err;
+
+ down_read(&mm->mmap_sem);
+ err = get_user_pages(current, current->mm, page_start,
+ 1 /* one page */,
+ 1 /* writable */,
+ 0 /* don't force */,
+ &page,
+ NULL /* don't return vmas */);
+ up_read(&mm->mmap_sem);
+
+ if (err < 0)
+ return ERR_PTR(err);
+ return page;
+}
+
+/* Simplified from arch/ppc/kernel/semaphore.c: Paul M. is a genius. */
+static int futex_down(struct list_head *head, atomic_t *count)
+{
+ struct futex_q q;
+
+ current->state = TASK_INTERRUPTIBLE;
+ q.count = count;
+ queue_me(head, &q);
+
+ /* It may have become available while we were adding ourselves
+ to queue? Also, make sure it's -ve so userspace knows
+ there's someone waiting. */
+ while ((atomic_read(count) < 0 || !atomic_dec_and_test(count))
+ && q.count != FUTEX_PASSED) {
+ schedule();
+ current->state = TASK_INTERRUPTIBLE;
+
+ if (signal_pending(current)) {
+ unqueue_me(&q);
+
+ /* We might have been passed futex anyway. */
+ return (q.count == FUTEX_PASSED) ? 0 : -EINTR;
+ }
+ }
+
+ /* We got the futex! */
+ current->state = TASK_RUNNING;
+ unqueue_me(&q);
+ return 0;
+}
+
+static int futex_fair_up(struct list_head *head, atomic_t *count)
+{
+ spin_lock(&futex_lock);
+ if (!pass_futex(head, count))
+ /* Noone to receive: set to one and leave it free. */
+ atomic_set(count, 1);
+ spin_unlock(&futex_lock);
+ return 0;
+}
+
+static int futex_up(struct list_head *head, atomic_t *count)
+{
+ atomic_set(count, 1);
+ smp_wmb();
+ wake_one_waiter(head, count);
+ return 0;
+}
+asmlinkage int sys_futex(void *uaddr, int op)
+{
+ int ret;
+ unsigned long pos_in_page;
+ struct list_head *head;
+ struct page *page;
+
+ pos_in_page = ((unsigned long)uaddr) % PAGE_SIZE;
+
+ /* Must be "naturally" aligned, and not on page boundary. */
+ if ((pos_in_page % __alignof__(atomic_t)) != 0
+ || pos_in_page + sizeof(atomic_t) > PAGE_SIZE)
+ return -EINVAL;
+
+ /* Simpler if it doesn't vanish underneath us. */
+ page = pin_page((unsigned long)uaddr - pos_in_page);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
+
+ head = hash_futex(page, pos_in_page);
+ switch (op) {
+ case FUTEX_DOWN:
+ ret = futex_down(head, page_address(page) + pos_in_page);
+ break;
+ case FUTEX_UP:
+ ret = futex_up(head, page_address(page) + pos_in_page);
+ break;
+ case FUTEX_UP_FAIR:
+ ret = futex_fair_up(head, page_address(page) + pos_in_page);
+ break;
+ /* Add other lock types here... */
+ default:
+ ret = -EINVAL;
+ }
+ put_page(page);
+
+ return ret;
+}
+
+static int __init init(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(futex_queues); i++)
+ INIT_LIST_HEAD(&futex_queues[i]);
+ return 0;
+}
+__initcall(init);
diff -urbN linux-2.5.5/mm/filemap.c linux-2.5.5-futex/mm/filemap.c
--- linux-2.5.5/mm/filemap.c Wed Mar 6 15:10:09 2002
+++ linux-2.5.5-futex/mm/filemap.c Wed Mar 6 11:40:12 2002
@@ -25,6 +25,7 @@
#include <linux/iobuf.h>
#include <linux/compiler.h>
#include <linux/fs.h>
+#include <linux/hash.h>
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
@@ -773,32 +774,8 @@
static inline wait_queue_head_t *page_waitqueue(struct page *page)
{
const zone_t *zone = page_zone(page);
- wait_queue_head_t *wait = zone->wait_table;
- unsigned long hash = (unsigned long)page;
-#if BITS_PER_LONG == 64
- /* Sigh, gcc can't optimise this alone like it does for 32 bits. */
- unsigned long n = hash;
- n <<= 18;
- hash -= n;
- n <<= 33;
- hash -= n;
- n <<= 3;
- hash += n;
- n <<= 3;
- hash -= n;
- n <<= 4;
- hash += n;
- n <<= 2;
- hash += n;
-#else
- /* On some cpus multiply is faster, on others gcc will do shifts */
- hash *= GOLDEN_RATIO_PRIME;
-#endif
-
- hash >>= zone->wait_table_shift;
-
- return &wait[hash];
+ return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
}
/*
diff -urbN linux-2.5.5/mm/mprotect.c linux-2.5.5-futex/mm/mprotect.c
--- linux-2.5.5/mm/mprotect.c Tue Feb 19 21:11:01 2002
+++ linux-2.5.5-futex/mm/mprotect.c Wed Mar 6 11:40:12 2002
@@ -280,7 +280,7 @@
end = start + len;
if (end < start)
return -EINVAL;
- if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
return -EINVAL;
if (end == start)
return 0;
diff -urbN linux-2.5.5/mm/page_alloc.c linux-2.5.5-futex/mm/page_alloc.c
--- linux-2.5.5/mm/page_alloc.c Tue Feb 19 21:10:55 2002
+++ linux-2.5.5-futex/mm/page_alloc.c Wed Mar 6 11:40:12 2002
@@ -776,8 +776,8 @@
* per zone.
*/
zone->wait_table_size = wait_table_size(size);
- zone->wait_table_shift =
- BITS_PER_LONG - wait_table_bits(zone->wait_table_size);
+ zone->wait_table_bits =
+ wait_table_bits(zone->wait_table_size);
zone->wait_table = (wait_queue_head_t *)
alloc_bootmem_node(pgdat, zone->wait_table_size
* sizeof(wait_queue_head_t));
next prev parent reply other threads:[~2002-03-06 20:35 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-03-05 7:01 [PATCH] Futexes IV (Fast Lightweight Userspace Semaphores) Rusty Russell
2002-03-05 21:23 ` Futexes III : performance numbers Hubertus Franke
2002-03-06 2:08 ` Rusty Russell
2002-03-06 14:28 ` Hubertus Franke
2002-03-06 17:23 ` [Lse-tech] " george anzinger
2002-03-07 0:25 ` Hubertus Franke
2002-03-07 0:35 ` Hubertus Franke
2002-03-06 7:54 ` Rusty Russell
2002-03-06 14:46 ` Hubertus Franke
2002-03-06 16:13 ` Hubertus Franke
2002-03-06 20:36 ` Hubertus Franke [this message]
2002-03-07 4:21 ` Futexes V : Rusty Russell
2002-03-05 22:39 ` [PATCH] Futexes IV (Fast Lightweight Userspace Semaphores) Davide Libenzi
2002-03-05 23:16 ` Hubertus Franke
2002-03-05 23:26 ` Davide Libenzi
2002-03-05 23:37 ` Peter Svensson
2002-03-05 23:50 ` Davide Libenzi
2002-03-08 0:07 ` Richard Henderson
2002-03-06 1:46 ` Rusty Russell
2002-03-06 2:03 ` Davide Libenzi
2002-03-08 18:07 ` Linus Torvalds
2002-03-08 19:03 ` Hubertus Franke
2002-03-08 19:22 ` Linus Torvalds
2002-03-08 20:29 ` Hubertus Franke
2002-03-08 20:48 ` Matthew Kirkwood
2002-03-08 21:02 ` Linus Torvalds
2002-03-08 23:15 ` Hubertus Franke
2002-03-08 23:36 ` Alan Cox
2002-03-08 23:41 ` Linus Torvalds
2002-03-08 23:56 ` Hubertus Franke
2002-03-09 2:12 ` Linus Torvalds
2002-03-11 14:14 ` Hubertus Franke
2002-03-09 0:03 ` H. Peter Anvin
2002-03-09 1:15 ` Alan Cox
2002-03-10 19:41 ` Linus Torvalds
2002-03-11 20:49 ` Pavel Machek
2002-03-13 7:40 ` Rusty Russell
2002-03-13 16:37 ` Alan Cox
2002-03-10 19:58 ` Martin J. Bligh
2002-03-10 20:40 ` Alan Cox
2002-03-10 20:28 ` Martin J. Bligh
2002-03-10 21:05 ` Alan Cox
2002-03-12 9:35 ` Helge Hafting
2002-03-08 20:40 ` Alan Cox
2002-03-08 20:57 ` Linus Torvalds
2002-03-08 23:43 ` H. Peter Anvin
2002-03-08 22:55 ` Hubertus Franke
2002-03-08 23:38 ` Alan Cox
2002-03-08 23:44 ` H. Peter Anvin
2002-03-08 20:47 ` george anzinger
2002-03-08 23:02 ` Hubertus Franke
2002-03-08 23:47 ` george anzinger
2002-03-09 1:11 ` Alan Cox
2002-03-09 1:20 ` Linus Torvalds
2002-03-09 4:49 ` Rusty Russell
2002-03-11 22:45 ` Linus Torvalds
2002-03-11 23:12 ` Hubertus Franke
2002-03-12 7:20 ` Rusty Russell
2002-03-12 14:56 ` Hubertus Franke
2002-03-13 4:02 ` Rusty Russell
2002-03-12 17:17 ` Linus Torvalds
2002-03-13 2:57 ` Rusty Russell
2002-03-09 4:51 ` Rusty Russell
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=20020306203522.4994A3FE06@smtp.linux.ibm.com \
--to=frankeh@watson.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lse-tech@lists.sourceforge.net \
--cc=rusty@rustcorp.com.au \
--cc=torvalds@transmeta.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.