From: Rusty Russell <rusty@rustcorp.com.au>
To: Hugh Dickins <hugh@veritas.com>
Cc: Ulrich Drepper <drepper@redhat.com>,
Jamie Lokier <lk@tantalophile.demon.co.uk>,
Andrew Morton <akpm@osdl.org>,
Stephen Hemminger <shemminger@osdl.org>,
torvalds@transmeta.com,
Linux Kernel <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] Re: today's futex changes
Date: Mon, 08 Sep 2003 16:45:47 +1000 [thread overview]
Message-ID: <20030908102309.0AC4E2C013@lists.samba.org> (raw)
In-Reply-To: Your message of "Sat, 06 Sep 2003 17:28:44 +0100." <Pine.LNX.4.44.0309061723160.1470-100000@localhost.localdomain>
In message <Pine.LNX.4.44.0309061723160.1470-100000@localhost.localdomain> you write:
> While here, please let's also fix the get_futex_key VM_NONLINEAR
> case, which was returning the 1 from get_user_pages, taken as an
> error by its callers. And save a few bytes and improve debuggability
> by uninlining the top-level futex_wake, futex_requeue, futex_wait.
OK, I've updated my patch on top of this. Mainly cosmetic, please
review.
Name: Minor Tweaks To Jamie Lokier's Futex Patch
Author: Rusty Russell
Status: Booted on 2.6.0-test4-bk9
Depends: Misc/futex-hugh.patch.gz
D: Minor changes to Jamie's excellent futex patch.
D: 1) Remove obsolete comment above hash array decl.
D: 2) Semantics of futex on read-only pages unclear: require write perm.
D: 3) Clarify comment about TASK_INTERRUPTIBLE.
D: 4) Andrew Morton says spurious wakeup is a bug. Catch it.
D: 5) Use Jenkins hash.
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .24731-linux-2.6.0-test4-bk9/kernel/futex.c .24731-linux-2.6.0-test4-bk9.updated/kernel/futex.c
--- .24731-linux-2.6.0-test4-bk9/kernel/futex.c 2003-09-08 10:44:26.000000000 +1000
+++ .24731-linux-2.6.0-test4-bk9.updated/kernel/futex.c 2003-09-08 12:01:23.000000000 +1000
@@ -33,7 +33,7 @@
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/file.h>
-#include <linux/hash.h>
+#include <linux/jhash.h>
#include <linux/init.h>
#include <linux/futex.h>
#include <linux/mount.h>
@@ -44,6 +44,7 @@
/*
* Futexes are matched on equal values of this key.
* The key type depends on whether it's a shared or private mapping.
+ * Don't rearrange without looking at hash_futex().
*/
union futex_key {
struct {
@@ -79,7 +80,6 @@ struct futex_q {
struct file *filp;
};
-/* The key for the hash is the address + index + offset within page */
static struct list_head futex_queues[1<<FUTEX_HASHBITS];
static spinlock_t futex_lock = SPIN_LOCK_UNLOCKED;
@@ -89,11 +89,12 @@ static struct vfsmount *futex_mnt;
/*
* We hash on the keys returned from get_futex_key (see below).
*/
-static inline struct list_head *hash_futex(union futex_key *key)
+static inline struct list_head *hash_futex(const union futex_key *key)
{
- return &futex_queues[hash_long(key->both.word
- + (unsigned long) key->both.ptr
- + key->both.offset, FUTEX_HASHBITS)];
+ u32 hash = jhash2((u32*)&key->both.word,
+ (sizeof(key->both.word)+sizeof(key->both.ptr))/4,
+ key->both.offset);
+ return &futex_queues[hash & ((1 << FUTEX_HASHBITS)-1)];
}
/*
@@ -145,17 +146,13 @@ static int get_futex_key(unsigned long u
/*
* Permissions.
*/
- if (unlikely((vma->vm_flags & (VM_IO|VM_READ)) != VM_READ))
- return (vma->vm_flags & VM_IO) ? -EPERM : -EACCES;
+ if (unlikely(vma->vm_flags & VM_IO))
+ return -EPERM;
+ if (unlikely(vma->vm_flags & (VM_READ|VM_WRITE)) != (VM_READ|VM_WRITE))
+ return -EACCES;
/*
* Private mappings are handled in a simple way.
- *
- * NOTE: When userspace waits on a MAP_SHARED mapping, even if
- * it's a read-only handle, it's expected that futexes attach to
- * the object not the particular process. Therefore we use
- * VM_MAYSHARE here, not VM_SHARED which is restricted to shared
- * mappings of _writable_ handles.
*/
if (likely(!(vma->vm_flags & VM_MAYSHARE))) {
key->private.mm = mm;
@@ -333,7 +330,6 @@ static int futex_wait(unsigned long uadd
union futex_key key;
struct futex_q q;
- try_again:
init_waitqueue_head(&q.waiters);
down_read(¤t->mm->mmap_sem);
@@ -367,10 +363,10 @@ static int futex_wait(unsigned long uadd
/*
* There might have been scheduling since the queue_me(), as we
* cannot hold a spinlock across the get_user() in case it
- * faults. So we cannot just set TASK_INTERRUPTIBLE state when
+ * faults, and we cannot just set TASK_INTERRUPTIBLE state when
* queueing ourselves into the futex hash. This code thus has to
- * rely on the futex_wake() code doing a wakeup after removing
- * the waiter from the list.
+ * rely on the futex_wake() code removing us from hash when it
+ * wakes us up.
*/
add_wait_queue(&q.waiters, &wait);
spin_lock(&futex_lock);
@@ -394,26 +390,19 @@ static int futex_wait(unsigned long uadd
* we are the only user of it.
*/
- /*
- * Were we woken or interrupted for a valid reason?
- */
- ret = unqueue_me(&q);
- if (ret == 0)
+ /* If we were woken (and unqueued), we succeeded, whatever. */
+ if (!unqueue_me(&q))
return 0;
if (time == 0)
return -ETIMEDOUT;
if (signal_pending(current))
return -EINTR;
- /*
- * No, it was a spurious wakeup. Try again. Should never happen. :)
- */
- goto try_again;
+ /* A spurious wakeup. Should never happen. */
+ BUG();
out_unqueue:
- /*
- * Were we unqueued anyway?
- */
+ /* If we were woken (and unqueued), we succeeded, whatever. */
if (!unqueue_me(&q))
ret = 0;
out_release_sem:
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
next prev parent reply other threads:[~2003-09-08 10:23 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-09-05 20:24 today's futex changes Ulrich Drepper
2003-09-05 22:24 ` Stephen Hemminger
2003-09-06 16:28 ` [PATCH] " Hugh Dickins
2003-09-06 17:32 ` Ulrich Drepper
2003-09-06 17:44 ` Jamie Lokier
2003-09-06 17:46 ` Jamie Lokier
2003-09-06 18:21 ` Hugh Dickins
2003-09-08 6:45 ` Rusty Russell [this message]
2003-09-08 17:33 ` Hugh Dickins
2003-09-08 17:51 ` Hugh Dickins
2003-09-09 1:37 ` Rusty Russell
2003-09-08 17:51 ` Jamie Lokier
2003-09-08 18:26 ` Jamie Lokier
2003-09-09 3:58 ` Rusty Russell
2003-09-10 11:39 ` Jamie Lokier
2003-09-10 22:00 ` Rusty Russell
2003-09-11 16:29 ` Jamie Lokier
2003-09-08 19:02 ` Andrew Morton
2003-09-08 20:07 ` Jamie Lokier
2003-09-08 19:59 ` Andrew Morton
2003-09-08 20:11 ` Linus Torvalds
2003-09-09 4:12 ` Rusty Russell
2003-09-08 17:04 ` Stephen Hemminger
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=20030908102309.0AC4E2C013@lists.samba.org \
--to=rusty@rustcorp.com.au \
--cc=akpm@osdl.org \
--cc=drepper@redhat.com \
--cc=hugh@veritas.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lk@tantalophile.demon.co.uk \
--cc=shemminger@osdl.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox