* [RESEND PATCH] futex: fix key reference counter in case of requeue. @ 2010-10-14 11:30 Louis Rilling 2010-10-15 12:16 ` Thomas Gleixner 2010-10-15 19:13 ` Darren Hart 0 siblings, 2 replies; 7+ messages in thread From: Louis Rilling @ 2010-10-14 11:30 UTC (permalink / raw) To: linux-kernel Cc: Rusty Russell, Ingo Molnar, Thomas Gleixner, Matthieu Fertré, Louis Rilling From: Matthieu Fertré <matthieu.fertre@kerlabs.com> This patch ensures that we are referring to the right key when dropping reference for the futex_wait operation. The following scenario explains a typical case where the bug was happening: Process P calls futex_wait() on futex identified by 'key1'. 2 references are taken on this key: one for the struct futex_q itself, and one for the futex_wait operation. If now, process P is requeued on a futex identified by 'key2', its futex_q->key is updated from 'key1' to 'key2' and a reference is got to 'key2' and one is dropped to 'key1'. Later, another process calls futex_wake(): it gets a reference to 'key2', wakes process P, and drops reference to 'key2'. Once process P is woken up, it should unqueue, drop reference to 'key2' (the one referring to the futex_q, this is done in unqueue_me()) and to 'key1' (the one referring to futex_wait operation). Without this patch it drops reference to 'key2' instead of 'key1'. Signed-off-by: Matthieu Fertré <matthieu.fertre@kerlabs.com> Signed-off-by: Louis Rilling <louis.rilling@kerlabs.com> --- kernel/futex.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 6a3a5fa..bed6717 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -1791,6 +1791,7 @@ static int futex_wait(u32 __user *uaddr, int fshared, struct restart_block *restart; struct futex_hash_bucket *hb; struct futex_q q; + union futex_key key; int ret; if (!bitset) @@ -1817,6 +1818,9 @@ retry: if (ret) goto out; + /* save the key in case of requeue. */ + key = q.key; + /* queue_me and wait for wakeup, timeout, or a signal. */ futex_wait_queue_me(hb, &q, to); @@ -1833,7 +1837,7 @@ retry: * victim of a spurious wakeup as well. */ if (!signal_pending(current)) { - put_futex_key(fshared, &q.key); + put_futex_key(fshared, &key); goto retry; } @@ -1857,7 +1861,7 @@ retry: ret = -ERESTART_RESTARTBLOCK; out_put_key: - put_futex_key(fshared, &q.key); + put_futex_key(fshared, &key); out: if (to) { hrtimer_cancel(&to->timer); -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RESEND PATCH] futex: fix key reference counter in case of requeue. 2010-10-14 11:30 [RESEND PATCH] futex: fix key reference counter in case of requeue Louis Rilling @ 2010-10-15 12:16 ` Thomas Gleixner 2010-10-15 19:19 ` Darren Hart 2010-10-18 12:14 ` Matthieu Fertré 2010-10-15 19:13 ` Darren Hart 1 sibling, 2 replies; 7+ messages in thread From: Thomas Gleixner @ 2010-10-15 12:16 UTC (permalink / raw) To: Louis Rilling Cc: LKML, Rusty Russell, Ingo Molnar, Matthieu Fertré, Darren Hart, Peter Zijlstra [-- Attachment #1: Type: TEXT/PLAIN, Size: 3428 bytes --] On Thu, 14 Oct 2010, Louis Rilling wrote: > From: Matthieu Fertré <matthieu.fertre@kerlabs.com> > > This patch ensures that we are referring to the right key when dropping > reference for the futex_wait operation. > > The following scenario explains a typical case where the bug was > happening: > > Process P calls futex_wait() on futex identified by 'key1'. 2 references > are taken on this key: one for the struct futex_q itself, and one for the > futex_wait operation. It took a while to understand that explanation. You mean we get one ref in get_key_ref() and one in queue_lock(), right ? > If now, process P is requeued on a futex identified by 'key2', its > futex_q->key is updated from 'key1' to 'key2' and a reference is got > to 'key2' and one is dropped to 'key1'. Correct. > Later, another process calls futex_wake(): it gets a reference to > 'key2', wakes process P, and drops reference to 'key2'. That's pretty irrelevant as this operation is symetrical. > Once process P is woken up, it should unqueue, drop reference to 'key2' > (the one referring to the futex_q, this is done in unqueue_me()) > and to 'key1' (the one referring to futex_wait operation). Without this > patch it drops reference to 'key2' instead of 'key1'. I can see the bug, but while the patch fixes it I don't think it is the proper solution. Aside of that we might have a similar problem in the futex_wait_requeue_pi() code. The real underlying problem is, that futex_wait_setup() returns with two references held in the case of success. That's what needs to be fixed in the first place. The futex_wait() case can be fixed with the patch below, still looking into the futex_wait_requeue_pi() maze. Darren, this whole key refcounting needs to be simplified _AND_ documented. Thanks, tglx --- Index: linux-2.6-tip/kernel/futex.c =================================================================== --- linux-2.6-tip.orig/kernel/futex.c +++ linux-2.6-tip/kernel/futex.c @@ -1786,8 +1786,14 @@ retry_private: } out: - if (ret) - put_futex_key(fshared, &q->key); + /* + * On success we hold here two references acquired in + * get_futex_key() and queue_lock(). Drop one. + * + * On failure we hold one reference acquired in + * get_futex_key(). Drop it. + */ + put_futex_key(fshared, &q->key); return ret; } @@ -1819,7 +1825,7 @@ static int futex_wait(u32 __user *uaddr, } retry: - /* Prepare to wait on uaddr. */ + /* Prepare to wait on uaddr. Hold hb lock and q.key ref on success */ ret = futex_wait_setup(uaddr, val, fshared, &q, &hb); if (ret) goto out; @@ -1829,24 +1835,23 @@ retry: /* If we were woken (and unqueued), we succeeded, whatever. */ ret = 0; + /* unqueue_me() drops q.key ref */ if (!unqueue_me(&q)) - goto out_put_key; + goto out; ret = -ETIMEDOUT; if (to && !to->task) - goto out_put_key; + goto out; /* * We expect signal_pending(current), but we might be the * victim of a spurious wakeup as well. */ - if (!signal_pending(current)) { - put_futex_key(fshared, &q.key); + if (!signal_pending(current)) goto retry; - } ret = -ERESTARTSYS; if (!abs_time) - goto out_put_key; + goto out; restart = ¤t_thread_info()->restart_block; restart->fn = futex_wait_restart; @@ -1863,8 +1868,6 @@ retry: ret = -ERESTART_RESTARTBLOCK; -out_put_key: - put_futex_key(fshared, &q.key); out: if (to) { hrtimer_cancel(&to->timer); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND PATCH] futex: fix key reference counter in case of requeue. 2010-10-15 12:16 ` Thomas Gleixner @ 2010-10-15 19:19 ` Darren Hart 2010-10-18 12:14 ` Matthieu Fertré 1 sibling, 0 replies; 7+ messages in thread From: Darren Hart @ 2010-10-15 19:19 UTC (permalink / raw) To: Thomas Gleixner Cc: Louis Rilling, LKML, Rusty Russell, Ingo Molnar, Matthieu Fertré, Darren Hart, Peter Zijlstra On 10/15/2010 05:16 AM, Thomas Gleixner wrote: > On Thu, 14 Oct 2010, Louis Rilling wrote: ... >> Once process P is woken up, it should unqueue, drop reference to 'key2' >> (the one referring to the futex_q, this is done in unqueue_me()) >> and to 'key1' (the one referring to futex_wait operation). Without this >> patch it drops reference to 'key2' instead of 'key1'. > > I can see the bug, but while the patch fixes it I don't think it is > the proper solution. Aside of that we might have a similar problem in > the futex_wait_requeue_pi() code. We do, and it's a bit more tangled. No surprises there. > The real underlying problem is, that futex_wait_setup() returns with > two references held in the case of success. That's what needs to be > fixed in the first place. > > The futex_wait() case can be fixed with the patch below, still looking > into the futex_wait_requeue_pi() maze. > > Darren, this whole key refcounting needs to be simplified _AND_ > documented. Agreed. We'll get this and futex_wait_requeue_pi fixed now, and then I'll spend some time cleaning this mess up after LPC. I'll test the following along with a wait_requeue_pi fix and report back. -- Darren > > Thanks, > > tglx > --- > Index: linux-2.6-tip/kernel/futex.c > =================================================================== > --- linux-2.6-tip.orig/kernel/futex.c > +++ linux-2.6-tip/kernel/futex.c > @@ -1786,8 +1786,14 @@ retry_private: > } > > out: > - if (ret) > - put_futex_key(fshared,&q->key); > + /* > + * On success we hold here two references acquired in > + * get_futex_key() and queue_lock(). Drop one. > + * > + * On failure we hold one reference acquired in > + * get_futex_key(). Drop it. > + */ > + put_futex_key(fshared,&q->key); > return ret; > } > > @@ -1819,7 +1825,7 @@ static int futex_wait(u32 __user *uaddr, > } > > retry: > - /* Prepare to wait on uaddr. */ > + /* Prepare to wait on uaddr. Hold hb lock and q.key ref on success */ > ret = futex_wait_setup(uaddr, val, fshared,&q,&hb); > if (ret) > goto out; > @@ -1829,24 +1835,23 @@ retry: > > /* If we were woken (and unqueued), we succeeded, whatever. */ > ret = 0; > + /* unqueue_me() drops q.key ref */ > if (!unqueue_me(&q)) > - goto out_put_key; > + goto out; > ret = -ETIMEDOUT; > if (to&& !to->task) > - goto out_put_key; > + goto out; > > /* > * We expect signal_pending(current), but we might be the > * victim of a spurious wakeup as well. > */ > - if (!signal_pending(current)) { > - put_futex_key(fshared,&q.key); > + if (!signal_pending(current)) > goto retry; > - } > > ret = -ERESTARTSYS; > if (!abs_time) > - goto out_put_key; > + goto out; > > restart =¤t_thread_info()->restart_block; > restart->fn = futex_wait_restart; > @@ -1863,8 +1868,6 @@ retry: > > ret = -ERESTART_RESTARTBLOCK; > > -out_put_key: > - put_futex_key(fshared,&q.key); > out: > if (to) { > hrtimer_cancel(&to->timer); -- Darren Hart Embedded Linux Kernel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND PATCH] futex: fix key reference counter in case of requeue. 2010-10-15 12:16 ` Thomas Gleixner 2010-10-15 19:19 ` Darren Hart @ 2010-10-18 12:14 ` Matthieu Fertré 1 sibling, 0 replies; 7+ messages in thread From: Matthieu Fertré @ 2010-10-18 12:14 UTC (permalink / raw) To: Thomas Gleixner Cc: Louis Rilling, LKML, Rusty Russell, Ingo Molnar, Darren Hart, Peter Zijlstra Le 15/10/2010 14:16, Thomas Gleixner a écrit : > On Thu, 14 Oct 2010, Louis Rilling wrote: > >> From: Matthieu Fertré <matthieu.fertre@kerlabs.com> >> >> This patch ensures that we are referring to the right key when dropping >> reference for the futex_wait operation. >> >> The following scenario explains a typical case where the bug was >> happening: >> >> Process P calls futex_wait() on futex identified by 'key1'. 2 references >> are taken on this key: one for the struct futex_q itself, and one for the >> futex_wait operation. > > It took a while to understand that explanation. You mean we get one > ref in get_key_ref() and one in queue_lock(), right ? > That's it. Sorry for the unclear explanation. Regards, Matthieu ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND PATCH] futex: fix key reference counter in case of requeue. 2010-10-14 11:30 [RESEND PATCH] futex: fix key reference counter in case of requeue Louis Rilling 2010-10-15 12:16 ` Thomas Gleixner @ 2010-10-15 19:13 ` Darren Hart 2010-10-15 19:18 ` Thomas Gleixner 2010-10-18 12:51 ` Matthieu Fertré 1 sibling, 2 replies; 7+ messages in thread From: Darren Hart @ 2010-10-15 19:13 UTC (permalink / raw) To: Louis Rilling Cc: linux-kernel, Rusty Russell, Ingo Molnar, Thomas Gleixner, Matthieu Fertré On 10/14/2010 04:30 AM, Louis Rilling wrote: > From: Matthieu Fertré<matthieu.fertre@kerlabs.com> Hi Matthew, > > This patch ensures that we are referring to the right key when dropping > reference for the futex_wait operation. > > The following scenario explains a typical case where the bug was > happening: > > Process P calls futex_wait() on futex identified by 'key1'. 2 references > are taken on this key: one for the struct futex_q itself, and one for the > futex_wait operation. > If now, process P is requeued on a futex identified by 'key2', its > futex_q->key is updated from 'key1' to 'key2' and a reference is got > to 'key2' and one is dropped to 'key1'. > Later, another process calls futex_wake(): it gets a reference to > 'key2', wakes process P, and drops reference to 'key2'. > Once process P is woken up, it should unqueue, drop reference to 'key2' > (the one referring to the futex_q, this is done in unqueue_me()) > and to 'key1' (the one referring to futex_wait operation). Without this > patch it drops reference to 'key2' instead of 'key1'. Nice catch. How did this manifest itself? Did you catch it just by code inspection? I've been trying to develop a futex test suite to catch issues with the futex implementation, as well as to test any changes made to avoid regressions. Mind having a look? http://git.kernel.org/?p=linux/kernel/git/dvhart/futextest.git;a=summary > Signed-off-by: Matthieu Fertré<matthieu.fertre@kerlabs.com> > Signed-off-by: Louis Rilling<louis.rilling@kerlabs.com> > --- > kernel/futex.c | 8 ++++++-- > 1 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/kernel/futex.c b/kernel/futex.c > index 6a3a5fa..bed6717 100644 > --- a/kernel/futex.c > +++ b/kernel/futex.c > @@ -1791,6 +1791,7 @@ static int futex_wait(u32 __user *uaddr, int fshared, > struct restart_block *restart; > struct futex_hash_bucket *hb; > struct futex_q q; > + union futex_key key; We should be able to do this properly without requiring an additional key variable. I think tglx has proposed a suitable fix - but it needs testing to avoid any subtle regressions. -- Darren Hart Embedded Linux Kernel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND PATCH] futex: fix key reference counter in case of requeue. 2010-10-15 19:13 ` Darren Hart @ 2010-10-15 19:18 ` Thomas Gleixner 2010-10-18 12:51 ` Matthieu Fertré 1 sibling, 0 replies; 7+ messages in thread From: Thomas Gleixner @ 2010-10-15 19:18 UTC (permalink / raw) To: Darren Hart Cc: Louis Rilling, linux-kernel, Rusty Russell, Ingo Molnar, Matthieu Fertré [-- Attachment #1: Type: TEXT/PLAIN, Size: 919 bytes --] On Fri, 15 Oct 2010, Darren Hart wrote: > On 10/14/2010 04:30 AM, Louis Rilling wrote: > > Signed-off-by: Matthieu Fertré<matthieu.fertre@kerlabs.com> > > Signed-off-by: Louis Rilling<louis.rilling@kerlabs.com> > > --- > > kernel/futex.c | 8 ++++++-- > > 1 files changed, 6 insertions(+), 2 deletions(-) > > > > diff --git a/kernel/futex.c b/kernel/futex.c > > index 6a3a5fa..bed6717 100644 > > --- a/kernel/futex.c > > +++ b/kernel/futex.c > > @@ -1791,6 +1791,7 @@ static int futex_wait(u32 __user *uaddr, int fshared, > > struct restart_block *restart; > > struct futex_hash_bucket *hb; > > struct futex_q q; > > + union futex_key key; > > We should be able to do this properly without requiring an additional key > variable. I think tglx has proposed a suitable fix - but it needs testing to > avoid any subtle regressions. Well, that still needs a look into wait_requeue_pi() :) Thanks, tglx ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RESEND PATCH] futex: fix key reference counter in case of requeue. 2010-10-15 19:13 ` Darren Hart 2010-10-15 19:18 ` Thomas Gleixner @ 2010-10-18 12:51 ` Matthieu Fertré 1 sibling, 0 replies; 7+ messages in thread From: Matthieu Fertré @ 2010-10-18 12:51 UTC (permalink / raw) To: Darren Hart Cc: Louis Rilling, linux-kernel, Rusty Russell, Ingo Molnar, Thomas Gleixner [-- Attachment #1: Type: text/plain, Size: 3502 bytes --] Hi Darren, Le 15/10/2010 21:13, Darren Hart a écrit : > On 10/14/2010 04:30 AM, Louis Rilling wrote: >> From: Matthieu Fertré<matthieu.fertre@kerlabs.com> > > Hi Matthew, > >> >> This patch ensures that we are referring to the right key when dropping >> reference for the futex_wait operation. >> >> The following scenario explains a typical case where the bug was >> happening: >> >> Process P calls futex_wait() on futex identified by 'key1'. 2 references >> are taken on this key: one for the struct futex_q itself, and one for the >> futex_wait operation. >> If now, process P is requeued on a futex identified by 'key2', its >> futex_q->key is updated from 'key1' to 'key2' and a reference is got >> to 'key2' and one is dropped to 'key1'. >> Later, another process calls futex_wake(): it gets a reference to >> 'key2', wakes process P, and drops reference to 'key2'. >> Once process P is woken up, it should unqueue, drop reference to 'key2' >> (the one referring to the futex_q, this is done in unqueue_me()) >> and to 'key1' (the one referring to futex_wait operation). Without this >> patch it drops reference to 'key2' instead of 'key1'. > > Nice catch. How did this manifest itself? Did you catch it just by code > inspection? I found it while testing the distributed implementation of futex in Kerrighed (www.kerrighed.org). After deeply looking, I noticed that the bug comes from vanilla linux kernel 2.6.30 (the one on which current version of Kerrighed is based). Then I checked if the bug still existed in latest linux rc or if there were some bugfixes. I have attached the test that reveals the bug on my system. The test runs some basic wait/wake/requeue scenario on futex "hosted" in a sysv shared memory segment. It is composed of one executable and 2 scripts that are to be used with LTP. To run it without LPT, you can replace calls to tst_resm/tst_brkm with echo in the shell scripts. Without debugging facilities, it may BUG while destroying the shared segment. As far as I remember, with some kernel hacking features enabled, it was complaining in the kernel log, but there was no crash and I don't remember exactly about what it complains. > > I've been trying to develop a futex test suite to catch issues with the > futex implementation, as well as to test any changes made to avoid > regressions. Mind having a look? > > http://git.kernel.org/?p=linux/kernel/git/dvhart/futextest.git;a=summary I had already a git checkout for this futex test suite :) It was not fitting to my tests since I was checking behavior of distributed futex inside Kerrighed. (I need test done by separate processes spreaded on different nodes accessing the futex through sysv shared segments). Regards, Matthieu > >> Signed-off-by: Matthieu Fertré<matthieu.fertre@kerlabs.com> >> Signed-off-by: Louis Rilling<louis.rilling@kerlabs.com> >> --- >> kernel/futex.c | 8 ++++++-- >> 1 files changed, 6 insertions(+), 2 deletions(-) >> >> diff --git a/kernel/futex.c b/kernel/futex.c >> index 6a3a5fa..bed6717 100644 >> --- a/kernel/futex.c >> +++ b/kernel/futex.c >> @@ -1791,6 +1791,7 @@ static int futex_wait(u32 __user *uaddr, int >> fshared, >> struct restart_block *restart; >> struct futex_hash_bucket *hb; >> struct futex_q q; >> + union futex_key key; > > We should be able to do this properly without requiring an additional > key variable. I think tglx has proposed a suitable fix - but it needs > testing to avoid any subtle regressions. > [-- Attachment #2: futex-shm-tool.c --] [-- Type: text/x-csrc, Size: 4890 bytes --] /* * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * Copyright (C) 2010 Kerlabs - Matthieu Fertré * * 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. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/mman.h> #include <asm/unistd.h> #include <linux/futex.h> #include <sys/time.h> static inline int futex(int *uaddr, int op, int val, const struct timespec *utime, int *uaddr2, int val3) { return syscall(__NR_futex, uaddr, op, val, utime, uaddr2, val3); } #define SYSERROR(X, Y) \ do { \ if ((long)(X) == -1L) { \ perror(Y); \ exit(EXIT_FAILURE); \ } \ } while(0) int shmkey = 23; int shmkey2 = 24; int nr_wake = 1; int nr_requeue = 1; int bitset = 0; int quiet = 0; struct timespec utime; void print_usage(const char* cmd) { printf("%s -h: show this help\n", cmd); } void dowait(void) { int shmid, ret, *f, n; struct timespec *timeout = NULL; shmid = shmget(shmkey, 4, IPC_CREAT|0666); SYSERROR(shmid, "shmget"); f = shmat(shmid, NULL, 0); SYSERROR(f, "shmat"); n = *f; if (utime.tv_sec) timeout = &utime; if (bitset) { if (!quiet) printf("WAIT_BITSET: %p{%x} bits: %x\n", f, n, bitset); ret = futex(f, FUTEX_WAIT_BITSET, n, timeout, NULL, bitset); } else { if (!quiet) printf("WAIT: %p{%x}\n", f, n); ret = futex(f, FUTEX_WAIT, n, timeout, NULL, 0); } SYSERROR(ret, "futex_wait"); if (!quiet) printf("WAITED: %d\n", ret); ret = shmdt(f); SYSERROR(ret, "shmdt"); } int dowake(void) { int shmid, ret, *f, nr_proc; shmid = shmget(shmkey, 4, IPC_CREAT|0666); SYSERROR(shmid, "shmget"); f = shmat(shmid, NULL, 0); SYSERROR(f, "shmat"); (*f)++; if (bitset) { if (!quiet) printf("WAKE_BITSET: %p{%x} bits: %x\n", f, *f, bitset); ret = futex(f, FUTEX_WAKE_BITSET, nr_wake, NULL, NULL, bitset); } else { if (!quiet) printf("WAKE: %p{%x}\n", f, *f); ret = futex(f, FUTEX_WAKE, nr_wake, NULL, NULL, 0); } SYSERROR(ret, "futex_wake"); if (!quiet) printf("WOKE: %d\n", ret); nr_proc = ret; ret = shmdt(f); SYSERROR(ret, "shmdt"); if (!ret) ret = nr_proc; return ret; } int dorequeue(void) { int shmid1, shmid2, ret, *f1, *f2, nr_proc; shmid1 = shmget(shmkey, 4, IPC_CREAT|0666); SYSERROR(shmid1, "shmget"); shmid2 = shmget(shmkey2, 4, IPC_CREAT|0666); SYSERROR(shmid2, "shmget"); f1 = shmat(shmid1, NULL, 0); SYSERROR(f1, "shmat"); f2 = shmat(shmid2, NULL, 0); SYSERROR(f2, "shmat"); /* requeue */ ret = futex(f1, FUTEX_REQUEUE, nr_wake, (const struct timespec *) (long) nr_requeue, f2, 0); SYSERROR(ret, "futex_requeue"); if (!quiet) printf("WOKE or REQUEUED: %d\n", ret); nr_proc = ret; /* detaching shms */ ret = shmdt(f1); SYSERROR(ret, "shmdt"); ret = shmdt(f2); SYSERROR(ret, "shmdt"); if (!ret) ret = nr_proc; return ret; } void badfutex(void) { int *x; int ret; x = mmap(NULL, 16384, PROT_READ, MAP_PRIVATE|MAP_ANON, -1, 0); SYSERROR(x, "mmap"); ret = futex(x, FUTEX_WAIT, 0, NULL, NULL, 0); SYSERROR(ret, "futex"); } void deletekey(void) { int shmid, ret; shmid = shmget(shmkey, 4, 0666); SYSERROR(shmid, "shmget"); ret = shmctl(shmid, IPC_RMID, NULL); SYSERROR(ret, "shmctl(IPC_RMID)"); if (!quiet) printf("SHM %d (id=%d) DELETED\n", shmkey, shmid); } void parse_args(int argc, char *argv[]) { int c; utime.tv_sec = 0; utime.tv_nsec = 0; while (1) { c = getopt(argc, argv, "hqb:k:K:r:t:w:"); if (c == -1) break; switch (c) { case 'h': print_usage(argv[0]); exit(EXIT_SUCCESS); break; case 'q': quiet=1; break; case 'b': bitset = atoi(optarg); break; case 'k': shmkey = atoi(optarg); break; case 'K': shmkey2 = atoi(optarg); break; case 'r': nr_requeue = atoi(optarg); break; case 't': utime.tv_sec = atoi(optarg); break; case 'w': nr_wake = atoi(optarg); break; } } } int main(int argc, char **argv) { char *action; int ret = 0; parse_args(argc, argv); if (argc - optind == 0) { print_usage(argv[0]); exit(EXIT_FAILURE); } action = argv[optind]; if (!quiet) printf("Command: %s\n", action); if (strcmp(action, "badfutex") == 0) badfutex(); else if (strcmp(action, "wait") == 0) dowait(); else if (strcmp(action, "wake") == 0) ret = dowake(); else if (strcmp(action, "requeue") == 0) ret = dorequeue(); else if (strcmp(action, "delete") == 0) deletekey(); else { fprintf(stderr, "Unknown command\n"); print_usage(argv[0]); exit(EXIT_FAILURE); } exit(ret); } [-- Attachment #3: futex_shm01.sh --] [-- Type: application/x-shellscript, Size: 3373 bytes --] [-- Attachment #4: lib_futex.sh --] [-- Type: application/x-shellscript, Size: 3044 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-10-18 12:51 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-10-14 11:30 [RESEND PATCH] futex: fix key reference counter in case of requeue Louis Rilling 2010-10-15 12:16 ` Thomas Gleixner 2010-10-15 19:19 ` Darren Hart 2010-10-18 12:14 ` Matthieu Fertré 2010-10-15 19:13 ` Darren Hart 2010-10-15 19:18 ` Thomas Gleixner 2010-10-18 12:51 ` Matthieu Fertré
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox