aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/futex.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2011-03-12 05:37:14 -0500
committerThomas Gleixner <tglx@linutronix.de>2011-03-12 05:43:32 -0500
commit995612178c88407d8330f580ba6572cb8b284dd8 (patch)
treeea19d21342814758a729ba931180146422393d15 /kernel/futex.c
parent8d7718aa082aaf30a0b4989e1f04858952f941bc (diff)
parent6d55da53db3d9b911f69f2ce1e5fb8943eafe057 (diff)
Merge branch 'tip/futex/devel' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-rt into core/futexes
futex,plist: Pass the real head of the priority list to plist_del() futex,plist: Remove debug lock assignment from plist_node plist: Shrink struct plist_head plist: Add priority list test
Diffstat (limited to 'kernel/futex.c')
-rw-r--r--kernel/futex.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 237f14bfc022..c6bef6e404fe 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -772,6 +772,24 @@ retry:
772 return ret; 772 return ret;
773} 773}
774 774
775/**
776 * __unqueue_futex() - Remove the futex_q from its futex_hash_bucket
777 * @q: The futex_q to unqueue
778 *
779 * The q->lock_ptr must not be NULL and must be held by the caller.
780 */
781static void __unqueue_futex(struct futex_q *q)
782{
783 struct futex_hash_bucket *hb;
784
785 if (WARN_ON(!q->lock_ptr || !spin_is_locked(q->lock_ptr)
786 || plist_node_empty(&q->list)))
787 return;
788
789 hb = container_of(q->lock_ptr, struct futex_hash_bucket, lock);
790 plist_del(&q->list, &hb->chain);
791}
792
775/* 793/*
776 * The hash bucket lock must be held when this is called. 794 * The hash bucket lock must be held when this is called.
777 * Afterwards, the futex_q must not be accessed. 795 * Afterwards, the futex_q must not be accessed.
@@ -789,7 +807,7 @@ static void wake_futex(struct futex_q *q)
789 */ 807 */
790 get_task_struct(p); 808 get_task_struct(p);
791 809
792 plist_del(&q->list, &q->list.plist); 810 __unqueue_futex(q);
793 /* 811 /*
794 * The waiting task can free the futex_q as soon as 812 * The waiting task can free the futex_q as soon as
795 * q->lock_ptr = NULL is written, without taking any locks. A 813 * q->lock_ptr = NULL is written, without taking any locks. A
@@ -1064,9 +1082,6 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1,
1064 plist_del(&q->list, &hb1->chain); 1082 plist_del(&q->list, &hb1->chain);
1065 plist_add(&q->list, &hb2->chain); 1083 plist_add(&q->list, &hb2->chain);
1066 q->lock_ptr = &hb2->lock; 1084 q->lock_ptr = &hb2->lock;
1067#ifdef CONFIG_DEBUG_PI_LIST
1068 q->list.plist.spinlock = &hb2->lock;
1069#endif
1070 } 1085 }
1071 get_futex_key_refs(key2); 1086 get_futex_key_refs(key2);
1072 q->key = *key2; 1087 q->key = *key2;
@@ -1093,16 +1108,12 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
1093 get_futex_key_refs(key); 1108 get_futex_key_refs(key);
1094 q->key = *key; 1109 q->key = *key;
1095 1110
1096 WARN_ON(plist_node_empty(&q->list)); 1111 __unqueue_futex(q);
1097 plist_del(&q->list, &q->list.plist);
1098 1112
1099 WARN_ON(!q->rt_waiter); 1113 WARN_ON(!q->rt_waiter);
1100 q->rt_waiter = NULL; 1114 q->rt_waiter = NULL;
1101 1115
1102 q->lock_ptr = &hb->lock; 1116 q->lock_ptr = &hb->lock;
1103#ifdef CONFIG_DEBUG_PI_LIST
1104 q->list.plist.spinlock = &hb->lock;
1105#endif
1106 1117
1107 wake_up_state(q->task, TASK_NORMAL); 1118 wake_up_state(q->task, TASK_NORMAL);
1108} 1119}
@@ -1450,9 +1461,6 @@ static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
1450 prio = min(current->normal_prio, MAX_RT_PRIO); 1461 prio = min(current->normal_prio, MAX_RT_PRIO);
1451 1462
1452 plist_node_init(&q->list, prio); 1463 plist_node_init(&q->list, prio);
1453#ifdef CONFIG_DEBUG_PI_LIST
1454 q->list.plist.spinlock = &hb->lock;
1455#endif
1456 plist_add(&q->list, &hb->chain); 1464 plist_add(&q->list, &hb->chain);
1457 q->task = current; 1465 q->task = current;
1458 spin_unlock(&hb->lock); 1466 spin_unlock(&hb->lock);
@@ -1497,8 +1505,7 @@ retry:
1497 spin_unlock(lock_ptr); 1505 spin_unlock(lock_ptr);
1498 goto retry; 1506 goto retry;
1499 } 1507 }
1500 WARN_ON(plist_node_empty(&q->list)); 1508 __unqueue_futex(q);
1501 plist_del(&q->list, &q->list.plist);
1502 1509
1503 BUG_ON(q->pi_state); 1510 BUG_ON(q->pi_state);
1504 1511
@@ -1518,8 +1525,7 @@ retry:
1518static void unqueue_me_pi(struct futex_q *q) 1525static void unqueue_me_pi(struct futex_q *q)
1519 __releases(q->lock_ptr) 1526 __releases(q->lock_ptr)
1520{ 1527{
1521 WARN_ON(plist_node_empty(&q->list)); 1528 __unqueue_futex(q);
1522 plist_del(&q->list, &q->list.plist);
1523 1529
1524 BUG_ON(!q->pi_state); 1530 BUG_ON(!q->pi_state);
1525 free_pi_state(q->pi_state); 1531 free_pi_state(q->pi_state);
@@ -2156,7 +2162,7 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
2156 * We were woken prior to requeue by a timeout or a signal. 2162 * We were woken prior to requeue by a timeout or a signal.
2157 * Unqueue the futex_q and determine which it was. 2163 * Unqueue the futex_q and determine which it was.
2158 */ 2164 */
2159 plist_del(&q->list, &q->list.plist); 2165 plist_del(&q->list, &hb->chain);
2160 2166
2161 /* Handle spurious wakeups gracefully */ 2167 /* Handle spurious wakeups gracefully */
2162 ret = -EWOULDBLOCK; 2168 ret = -EWOULDBLOCK;