diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2011-03-12 05:37:14 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2011-03-12 05:43:32 -0500 |
commit | 995612178c88407d8330f580ba6572cb8b284dd8 (patch) | |
tree | ea19d21342814758a729ba931180146422393d15 /kernel/futex.c | |
parent | 8d7718aa082aaf30a0b4989e1f04858952f941bc (diff) | |
parent | 6d55da53db3d9b911f69f2ce1e5fb8943eafe057 (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.c | 40 |
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 | */ | ||
781 | static 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: | |||
1518 | static void unqueue_me_pi(struct futex_q *q) | 1525 | static 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; |