rpms/kernel/devel kernel-2.6.spec, 1.2470, 1.2471 linux-2.6-futex-death-fix.patch, 1.1, 1.2
fedora-cvs-commits at redhat.com
fedora-cvs-commits at redhat.com
Fri Jul 28 17:57:28 UTC 2006
- Previous message (by thread): rpms/selinux-policy/devel modules-strict.conf, 1.13, 1.14 modules-targeted.conf, 1.30, 1.31 policy-20060608.patch, 1.40, 1.41 selinux-policy.spec, 1.236, 1.237
- Next message (by thread): rpms/fedora-logos/devel .cvsignore, 1.28, 1.29 fedora-logos.spec, 1.34, 1.35 sources, 1.30, 1.31
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: davej
Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv3601
Modified Files:
kernel-2.6.spec linux-2.6-futex-death-fix.patch
Log Message:
update patch to latest
Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.2470
retrieving revision 1.2471
diff -u -r1.2470 -r1.2471
--- kernel-2.6.spec 28 Jul 2006 04:32:46 -0000 1.2470
+++ kernel-2.6.spec 28 Jul 2006 17:57:26 -0000 1.2471
@@ -1663,6 +1663,9 @@
%endif
%changelog
+* Fri Jul 28 2006 Dave Jones <davej at redhat.com>
+- Update futex-death patch.
+
* Thu Jul 27 2006 Roland McGrath <roland at redhat.com>
- s390 utrace fix
linux-2.6-futex-death-fix.patch:
include/linux/futex.h | 3 +
kernel/futex.c | 91 ++++++++++++++++++++++++++++++++++----------------
kernel/futex_compat.c | 34 +++++++++++++-----
3 files changed, 89 insertions(+), 39 deletions(-)
Index: linux-2.6-futex-death-fix.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/linux-2.6-futex-death-fix.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- linux-2.6-futex-death-fix.patch 12 Jul 2006 15:16:00 -0000 1.1
+++ linux-2.6-futex-death-fix.patch 28 Jul 2006 17:57:26 -0000 1.2
@@ -1,42 +1,307 @@
-
-Dave,
-
-could you apply the patch below to Fedora, to make sure we have this
-tested by Ulrich before i send it upstream?
-
-Jakub, do you agree with this approach?
-
- Ingo
-
-------->
Subject: pi-futex: robust-futex exit
From: Ingo Molnar <mingo at elte.hu>
fix robust PI-futexes to be properly unlocked on unexpected exit.
+for this the kernel has to know whether a futex is a PI or a non-PI
+one, because the semantics are different. Since the space in relevant
+glibc data structures is extremely scarce, the best solution is to
+encode the 'PI' information in bit 0 of the robust list pointer.
+Existing (non-PI) glibc robust futexes have this bit always zero,
+so the ABI is kept. New glibc with PI-robust-futexes will set this
+bit.
+
+further fixes:
+
+From: Thomas Gleixner <tglx at linutronix.de>
+
Signed-off-by: Ingo Molnar <mingo at elte.hu>
+Signed-off-by: Ulrich Drepper <drepper at redhat.com>
+Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
---
- kernel/futex.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
+ include/linux/futex.h | 3 +
+ kernel/futex.c | 91 ++++++++++++++++++++++++++++++++++----------------
+ kernel/futex_compat.c | 34 +++++++++++++-----
+ 3 files changed, 89 insertions(+), 39 deletions(-)
-Index: linux-pi-futex.q/kernel/futex.c
+Index: linux/include/linux/futex.h
+===================================================================
+--- linux.orig/include/linux/futex.h
++++ linux/include/linux/futex.h
+@@ -96,7 +96,8 @@ struct robust_list_head {
+ long do_futex(u32 __user *uaddr, int op, u32 val, unsigned long timeout,
+ u32 __user *uaddr2, u32 val2, u32 val3);
+
+-extern int handle_futex_death(u32 __user *uaddr, struct task_struct *curr);
++extern int
++handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi);
+
+ #ifdef CONFIG_FUTEX
+ extern void exit_robust_list(struct task_struct *curr);
+Index: linux/kernel/futex.c
===================================================================
---- linux-pi-futex.q.orig/kernel/futex.c
-+++ linux-pi-futex.q/kernel/futex.c
-@@ -1696,8 +1696,15 @@ retry:
+--- linux.orig/kernel/futex.c
++++ linux/kernel/futex.c
+@@ -495,10 +495,13 @@ lookup_pi_state(u32 uval, struct futex_h
+ }
+
+ /*
+- * We are the first waiter - try to look up the real owner and
+- * attach the new pi_state to it:
++ * We are the first waiter - try to look up the real owner and attach
++ * the new pi_state to it, but bail out when the owner died bit is set
++ * and TID = 0:
+ */
+ pid = uval & FUTEX_TID_MASK;
++ if (!pid && (uval & FUTEX_OWNER_DIED))
++ return -ESRCH;
+ p = futex_find_get_task(pid);
+ if (!p)
+ return -ESRCH;
+@@ -579,16 +582,17 @@ static int wake_futex_pi(u32 __user *uad
+ * kept enabled while there is PI state around. We must also
+ * preserve the owner died bit.)
+ */
+- newval = (uval & FUTEX_OWNER_DIED) | FUTEX_WAITERS | new_owner->pid;
+-
+- inc_preempt_count();
+- curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval);
+- dec_preempt_count();
++ if (!(uval & FUTEX_OWNER_DIED)) {
++ newval = FUTEX_WAITERS | new_owner->pid;
+
+- if (curval == -EFAULT)
+- return -EFAULT;
+- if (curval != uval)
+- return -EINVAL;
++ inc_preempt_count();
++ curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval);
++ dec_preempt_count();
++ if (curval == -EFAULT)
++ return -EFAULT;
++ if (curval != uval)
++ return -EINVAL;
++ }
+
+ spin_lock_irq(&pi_state->owner->pi_lock);
+ WARN_ON(list_empty(&pi_state->list));
+@@ -1443,9 +1447,11 @@ retry_locked:
+ * again. If it succeeds then we can return without waking
+ * anyone else up:
+ */
+- inc_preempt_count();
+- uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0);
+- dec_preempt_count();
++ if (!(uval & FUTEX_OWNER_DIED)) {
++ inc_preempt_count();
++ uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0);
++ dec_preempt_count();
++ }
+
+ if (unlikely(uval == -EFAULT))
+ goto pi_faulted;
+@@ -1478,9 +1484,11 @@ retry_locked:
+ /*
+ * No waiters - kernel unlocks the futex:
+ */
+- ret = unlock_futex_pi(uaddr, uval);
+- if (ret == -EFAULT)
+- goto pi_faulted;
++ if (!(uval & FUTEX_OWNER_DIED)) {
++ ret = unlock_futex_pi(uaddr, uval);
++ if (ret == -EFAULT)
++ goto pi_faulted;
++ }
+
+ out_unlock:
+ spin_unlock(&hb->lock);
+@@ -1699,9 +1707,9 @@ err_unlock:
+ * Process a futex-list entry, check whether it's owned by the
+ * dying task, and do notification if so:
+ */
+-int handle_futex_death(u32 __user *uaddr, struct task_struct *curr)
++int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi)
+ {
+- u32 uval, nval;
++ u32 uval, nval, mval;
+
+ retry:
+ if (get_user(uval, uaddr))
+@@ -1718,21 +1726,45 @@ retry:
+ * thread-death.) The rest of the cleanup is done in
+ * userspace.
+ */
+- nval = futex_atomic_cmpxchg_inatomic(uaddr, uval,
+- uval | FUTEX_OWNER_DIED);
++ mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
++ nval = futex_atomic_cmpxchg_inatomic(uaddr, uval, mval);
++
+ if (nval == -EFAULT)
+ return -1;
+
if (nval != uval)
goto retry;
- if (uval & FUTEX_WAITERS)
-+ if (uval & FUTEX_WAITERS) {
-+ /*
-+ * It's either a normal futex or a PI futex,
-+ * their wake handlers will determine this
-+ * and only one will succeed:
-+ */
- futex_wake(uaddr, 1);
-+ futex_unlock_pi(uaddr);
+- futex_wake(uaddr, 1);
++ /*
++ * Wake robust non-PI futexes here. The wakeup of
++ * PI futexes happens in exit_pi_state():
++ */
++ if (!pi) {
++ if (uval & FUTEX_WAITERS)
++ futex_wake(uaddr, 1);
+ }
}
return 0;
}
+
+ /*
++ * Fetch a robust-list pointer. Bit 0 signals PI futexes:
++ */
++static inline int fetch_robust_entry(struct robust_list __user **entry,
++ struct robust_list __user **head, int *pi)
++{
++ unsigned long uentry;
++
++ if (get_user(uentry, (unsigned long *)head))
++ return -EFAULT;
++
++ *entry = (void *)(uentry & ~1UL);
++ *pi = uentry & 1;
++
++ return 0;
++}
++
++/*
+ * Walk curr->robust_list (very carefully, it's a userspace list!)
+ * and mark any locks found there dead, and notify any waiters.
+ *
+@@ -1742,14 +1774,14 @@ void exit_robust_list(struct task_struct
+ {
+ struct robust_list_head __user *head = curr->robust_list;
+ struct robust_list __user *entry, *pending;
+- unsigned int limit = ROBUST_LIST_LIMIT;
++ unsigned int limit = ROBUST_LIST_LIMIT, pi, pip;
+ unsigned long futex_offset;
+
+ /*
+ * Fetch the list head (which was registered earlier, via
+ * sys_set_robust_list()):
+ */
+- if (get_user(entry, &head->list.next))
++ if (fetch_robust_entry(&entry, &head->list.next, &pi))
+ return;
+ /*
+ * Fetch the relative futex offset:
+@@ -1760,10 +1792,11 @@ void exit_robust_list(struct task_struct
+ * Fetch any possibly pending lock-add first, and handle it
+ * if it exists:
+ */
+- if (get_user(pending, &head->list_op_pending))
++ if (fetch_robust_entry(&pending, &head->list_op_pending, &pip))
+ return;
++
+ if (pending)
+- handle_futex_death((void *)pending + futex_offset, curr);
++ handle_futex_death((void *)pending + futex_offset, curr, pip);
+
+ while (entry != &head->list) {
+ /*
+@@ -1772,12 +1805,12 @@ void exit_robust_list(struct task_struct
+ */
+ if (entry != pending)
+ if (handle_futex_death((void *)entry + futex_offset,
+- curr))
++ curr, pi))
+ return;
+ /*
+ * Fetch the next entry in the list:
+ */
+- if (get_user(entry, &entry->next))
++ if (fetch_robust_entry(&entry, &entry->next, &pi))
+ return;
+ /*
+ * Avoid excessively long or circular lists:
+Index: linux/kernel/futex_compat.c
+===================================================================
+--- linux.orig/kernel/futex_compat.c
++++ linux/kernel/futex_compat.c
+@@ -12,6 +12,23 @@
+
+ #include <asm/uaccess.h>
+
++
++/*
++ * Fetch a robust-list pointer. Bit 0 signals PI futexes:
++ */
++static inline int
++fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
++ compat_uptr_t *head, int *pi)
++{
++ if (get_user(*uentry, head))
++ return -EFAULT;
++
++ *entry = compat_ptr((*uentry) & ~1);
++ *pi = (unsigned int)(*uentry) & 1;
++
++ return 0;
++}
++
+ /*
+ * Walk curr->robust_list (very carefully, it's a userspace list!)
+ * and mark any locks found there dead, and notify any waiters.
+@@ -22,17 +39,16 @@ void compat_exit_robust_list(struct task
+ {
+ struct compat_robust_list_head __user *head = curr->compat_robust_list;
+ struct robust_list __user *entry, *pending;
++ unsigned int limit = ROBUST_LIST_LIMIT, pi;
+ compat_uptr_t uentry, upending;
+- unsigned int limit = ROBUST_LIST_LIMIT;
+ compat_long_t futex_offset;
+
+ /*
+ * Fetch the list head (which was registered earlier, via
+ * sys_set_robust_list()):
+ */
+- if (get_user(uentry, &head->list.next))
++ if (fetch_robust_entry(&uentry, &entry, &head->list.next, &pi))
+ return;
+- entry = compat_ptr(uentry);
+ /*
+ * Fetch the relative futex offset:
+ */
+@@ -42,11 +58,11 @@ void compat_exit_robust_list(struct task
+ * Fetch any possibly pending lock-add first, and handle it
+ * if it exists:
+ */
+- if (get_user(upending, &head->list_op_pending))
++ if (fetch_robust_entry(&upending, &pending,
++ &head->list_op_pending, &pi))
+ return;
+- pending = compat_ptr(upending);
+ if (upending)
+- handle_futex_death((void *)pending + futex_offset, curr);
++ handle_futex_death((void *)pending + futex_offset, curr, pi);
+
+ while (compat_ptr(uentry) != &head->list) {
+ /*
+@@ -55,15 +71,15 @@ void compat_exit_robust_list(struct task
+ */
+ if (entry != pending)
+ if (handle_futex_death((void *)entry + futex_offset,
+- curr))
++ curr, pi))
+ return;
+
+ /*
+ * Fetch the next entry in the list:
+ */
+- if (get_user(uentry, (compat_uptr_t *)&entry->next))
++ if (fetch_robust_entry(&uentry, &entry,
++ (compat_uptr_t *)&entry->next, &pi))
+ return;
+- entry = compat_ptr(uentry);
+ /*
+ * Avoid excessively long or circular lists:
+ */
- Previous message (by thread): rpms/selinux-policy/devel modules-strict.conf, 1.13, 1.14 modules-targeted.conf, 1.30, 1.31 policy-20060608.patch, 1.40, 1.41 selinux-policy.spec, 1.236, 1.237
- Next message (by thread): rpms/fedora-logos/devel .cvsignore, 1.28, 1.29 fedora-logos.spec, 1.34, 1.35 sources, 1.30, 1.31
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-cvs-commits
mailing list