- futex_requeue_pi implementation (requeue from futex1 to PI-futex2)
RFC PATCH 1/1 - futex_requeue_pi implementation (requeue from futex1 to PI-futex2)
Hi,
First, thanks Ingo for your comments on my previous mail from december. I've taken all your remarks into account.
The 64-bit and compat versions have been implemented and tested.
The glibc part has also been updated and the x86_64 version is now implemented too.
Here after is the updated patch for kernel 2.6.19-rt15.
Comments, suggestions, feedbacks are welcome, as usual.
---
With the introduction of the PI-futex (used for the PI-pthread_mutex in the glibc), the current futex_requeue optimization (*) can not be used any more if the pthread_mutex used with the pthread-condvar is a PI-mutex.
(*) this optimization is used in pthread_cond_broadcast.
To use this optimization with PI-mutex, we need a function that re-queues some threads from a normal futex to a PI-futex (see why in this discussion:
http://marc.theaimsgroup.com/?l=linux-kernel&m=115020355126851&w=2 )
Here is a proposal of an implementation of futex_requeue_pi.
To use or test this patch with pthreads, you need to patch the glibc with the patch available here:
http://www.bullopensource.org/posix/pi-futex/glibc_requeue_pi.diff
(Only available for ix86 and x86_64 architecture)
or use the generic pthread_cond_broadcast.c file (patch here:
http://www.bullopensource.org/posix/pi-futex/glibc_pth_broadcast_c_file.diff
)
---
include/linux/futex.h | 8 kernel/futex.c | 1076 ++++++++++++++++++++++++++++++++++++++++++------ kernel/futex_compat.c | 3 kernel/rtmutex.c | 43 - kernel/rtmutex_common.h | 36 + 5 files changed, 1013 insertions(+), 153 deletions(-)
---
---
include/linux/futex.h +7 -1
@@ -15,6 +15,7 @@#define FUTEX_LOCK_PI 6#define FUTEX_UNLOCK_PI 7#define FUTEX_TRYLOCK_PI 8 +#define FUTEX_CMP_REQUEUE_PI 9/* * Support for robust futexes: the kernel cleans up held futexes at
@@ -83,9 +84,14 @@ struct robust_list_head {#define FUTEX_OWNER_DIED 0x40000000/* +* Some processes have been requeued on this PI-futex +*/ +#define FUTEX_WAITER_REQUEUED 0x20000000 + +/* * The rest of the robust-futex field is for the TID: */ -#define FUTEX_TID_MASK 0x3fffffff +#define FUTEX_TID_MASK 0x0fffffff/* * This limit protects against a deliberately circular list.
kernel/futex.c +958 -118
1,396 lines not on this page · raw message
kernel/rtmutex.c +10 -33
73 lines not on this page · raw message
kernel/rtmutex_common.h +36 -0
@@ -113,6 +113,30 @@ static inline unsigned long rt_mutex_own }/* +* We can speed up the acquire/release, if the architecture +* supports cmpxchg and if there's no debugging state to be set up +*/ +#if defined(__HAVE_ARCH_CMPXCHG) && !defined(CONFIG_DEBUG_RT_MUTEXES ) +# define rt_mutex_cmpxchg (l,c,n) (cmpxchg(&l->owner, c, n) == c) +static inline void mark_rt_mutex_waiters (struct rt_mutex *lock) +{ +unsigned long owner, *p = (unsigned long *) &lock->owner; + +do { + owner = *p; +cpu_relax (); + }while (cmpxchg (p, owner, owner |RT_MUTEX_HAS_WAITERS ) != owner); +} +#else +# define rt_mutex_cmpxchg (l,c,n) (0) +static inline void mark_rt_mutex_waiters (struct rt_mutex *lock) +{ + lock->owner = (struct task_struct *) + ((unsigned long )lock->owner |RT_MUTEX_HAS_WAITERS ); +} +#endif + +/* * PI-futex support (proxy locking functions, etc.): */ extern struct task_struct *rt_mutex_next_owner (struct rt_mutex *lock);
@@ -120,4 +144,16 @@ extern void rt_mutex_init_proxy_locked(s struct task_struct *proxy_owner);extern void rt_mutex_proxy_unlock (struct rt_mutex *lock,struct task_struct *proxy_owner); + +extern void rt_mutex_set_owner (struct rt_mutex *lock,struct task_struct *owner, +unsigned long mask); +extern void __rt_mutex_adjust_prio (struct task_struct *task); +extern int rt_mutex_adjust_prio_chain (struct task_struct *task, +int deadlock_detect, +struct rt_mutex *orig_lock, +struct rt_mutex_waiter *orig_waiter, +struct task_struct *top_task); +extern void remove_waiter (struct rt_mutex *lock, +struct rt_mutex_waiter *waiter, +unsigned long flags);#endif
kernel/futex_compat.c +2 -1
@@ -150,7 +150,8 @@ asmlinkage long compat_sys_futex(u32 __uif (!timespec_valid (&t))return -EINVAL ; } -if (op ==FUTEX_REQUEUE || op ==FUTEX_CMP_REQUEUE ) +if (op ==FUTEX_REQUEUE || op ==FUTEX_CMP_REQUEUE + || op ==FUTEX_CMP_REQUEUE_PI ) val2 = (int ) (unsigned long ) utime;return do_futex (uaddr, op, val, &t, uaddr2, val2, val3);
Thanks,
Signature · 1 line
Pierre Peiffer
Quoted 10 lines · Pierre Peiffer
Hi,
First, thanks Ingo for your comments on my previous mail from december. I've taken all your remarks into account.
The 64-bit and compat versions have been implemented and tested. The glibc part has also been updated and the
x86_64version is now implemented too.Here after is the updated patch for kernel 2.6.19-rt15.
looks good to me in principle. The size of the patch is scary - is there really no simpler way? Also, could you send me a patch against a 20-rc3-rt0-ish kernel so that i can stick this into -rt for testing?
Ingo
Quoted 2 lines · Ingo Molnar
looks good to me in principle. The size of the patch is scary - is there really no simpler way?
Humf, in fact, for the 64-bit part, I've followed the rule of the existing 64-bit code in futex.c, which consists of duplicating all the functions which can not be kept common, and add a suffix 64 to all duplicated functions. Perhaps I missed something ?
Quoted 2 lines
Also, could you send me a patch against a 20-rc3-rt0-ish kernel so that i can stick this into -rt for testing?
Ok, will do that.
Thanks,
Signature · 1 line
Pierre Peiffer
Quoted 9 lines · Pierre Peiffer
Quoted 3 lines · Ingo Molnar
looks good to me in principle. The size of the patch is scary - is there really no simpler way?
Humf, in fact, for the 64-bit part, I've followed the rule of the existing 64-bit code in
futex.c, which consists of duplicating all the functions which can not be kept common, and add a suffix 64 to all duplicated functions. Perhaps I missed something ?
i dont think you missed anything - but some consolidation here would be nice. Only if possible of course :-)
Ingo
Quoted 7 lines · Ingo Molnar
Quoted 3 lines · Pierre Peiffer
Quoted 1 line · Ingo Molnar
looks good to me in principle. The size of the patch is scary - is there really no simpler way?
Humf, in fact, for the 64-bit part, I've followed the rule of the existing 64-bit code in
futex.c, which consists of duplicating all the functions which can not be kept common, and add a suffix 64 to all duplicated functions. Perhaps I missed something ?i dont think you missed anything - but some consolidation here would be nice. Only if possible of course :-)
Ok ;-)
So, you are not only speaking about "my" part of duplicated code, right ?
But, just for information, what is the sys_futex64 for, exactly ? Is there a plan to have in the future a 64-bit PID ? Because for now, 32-bits futex is enough, so... ? Otherwise, I don't have a "clean" way to avoid this duplication.... :-/
Signature · 1 line
Pierre Peiffer
Quoted 2 lines · Pierre Peiffer
But, just for information, what is the
sys_futex64for, exactly ? Is there a plan to have in the future a 64-bit PID ?
This has nothing to do with PIDs. We need 64-bit values for more complex bit fields which can then be stored in the futex. One example is a new, much faster rwlock implementation. These are not practical without 64-bit futexes. This is why I asked Ingo to add the code.
Signature · 1 line
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖