diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2009-11-17 08:46:14 -0500 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2009-12-14 17:55:33 -0500 |
| commit | a26724591edba5acc528d41f3906a972590e8f54 (patch) | |
| tree | 4e7a1c7c7e4b19b428222da9232aa7322439e243 | |
| parent | fa4062e7eae8f484c90b9cdd850b5df39ab0e5a0 (diff) | |
plist: Make plist debugging raw_spinlock aware
plists are used with spinlocks and raw_spinlocks. Change the plist
debugging to handle both types.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Acked-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | include/linux/plist.h | 43 | ||||
| -rw-r--r-- | kernel/futex.c | 6 | ||||
| -rw-r--r-- | lib/plist.c | 8 |
3 files changed, 45 insertions, 12 deletions
diff --git a/include/linux/plist.h b/include/linux/plist.h index 45926d77d6ac..8227f717c70f 100644 --- a/include/linux/plist.h +++ b/include/linux/plist.h | |||
| @@ -81,7 +81,8 @@ struct plist_head { | |||
| 81 | struct list_head prio_list; | 81 | struct list_head prio_list; |
| 82 | struct list_head node_list; | 82 | struct list_head node_list; |
| 83 | #ifdef CONFIG_DEBUG_PI_LIST | 83 | #ifdef CONFIG_DEBUG_PI_LIST |
| 84 | spinlock_t *lock; | 84 | raw_spinlock_t *rawlock; |
| 85 | spinlock_t *spinlock; | ||
| 85 | #endif | 86 | #endif |
| 86 | }; | 87 | }; |
| 87 | 88 | ||
| @@ -91,9 +92,11 @@ struct plist_node { | |||
| 91 | }; | 92 | }; |
| 92 | 93 | ||
| 93 | #ifdef CONFIG_DEBUG_PI_LIST | 94 | #ifdef CONFIG_DEBUG_PI_LIST |
| 94 | # define PLIST_HEAD_LOCK_INIT(_lock) .lock = _lock | 95 | # define PLIST_HEAD_LOCK_INIT(_lock) .spinlock = _lock |
| 96 | # define PLIST_HEAD_LOCK_INIT_RAW(_lock) .rawlock = _lock | ||
| 95 | #else | 97 | #else |
| 96 | # define PLIST_HEAD_LOCK_INIT(_lock) | 98 | # define PLIST_HEAD_LOCK_INIT(_lock) |
| 99 | # define PLIST_HEAD_LOCK_INIT_RAW(_lock) | ||
| 97 | #endif | 100 | #endif |
| 98 | 101 | ||
| 99 | #define _PLIST_HEAD_INIT(head) \ | 102 | #define _PLIST_HEAD_INIT(head) \ |
| @@ -107,11 +110,22 @@ struct plist_node { | |||
| 107 | */ | 110 | */ |
| 108 | #define PLIST_HEAD_INIT(head, _lock) \ | 111 | #define PLIST_HEAD_INIT(head, _lock) \ |
| 109 | { \ | 112 | { \ |
| 110 | _PLIST_HEAD_INIT(head), \ | 113 | _PLIST_HEAD_INIT(head), \ |
| 111 | PLIST_HEAD_LOCK_INIT(&(_lock)) \ | 114 | PLIST_HEAD_LOCK_INIT(&(_lock)) \ |
| 112 | } | 115 | } |
| 113 | 116 | ||
| 114 | /** | 117 | /** |
| 118 | * PLIST_HEAD_INIT_RAW - static struct plist_head initializer | ||
| 119 | * @head: struct plist_head variable name | ||
| 120 | * @_lock: lock to initialize for this list | ||
| 121 | */ | ||
| 122 | #define PLIST_HEAD_INIT_RAW(head, _lock) \ | ||
| 123 | { \ | ||
| 124 | _PLIST_HEAD_INIT(head), \ | ||
| 125 | PLIST_HEAD_LOCK_INIT_RAW(&(_lock)) \ | ||
| 126 | } | ||
| 127 | |||
| 128 | /** | ||
| 115 | * PLIST_NODE_INIT - static struct plist_node initializer | 129 | * PLIST_NODE_INIT - static struct plist_node initializer |
| 116 | * @node: struct plist_node variable name | 130 | * @node: struct plist_node variable name |
| 117 | * @__prio: initial node priority | 131 | * @__prio: initial node priority |
| @@ -119,13 +133,13 @@ struct plist_node { | |||
| 119 | #define PLIST_NODE_INIT(node, __prio) \ | 133 | #define PLIST_NODE_INIT(node, __prio) \ |
| 120 | { \ | 134 | { \ |
| 121 | .prio = (__prio), \ | 135 | .prio = (__prio), \ |
| 122 | .plist = { _PLIST_HEAD_INIT((node).plist) }, \ | 136 | .plist = { _PLIST_HEAD_INIT((node).plist) }, \ |
| 123 | } | 137 | } |
| 124 | 138 | ||
| 125 | /** | 139 | /** |
| 126 | * plist_head_init - dynamic struct plist_head initializer | 140 | * plist_head_init - dynamic struct plist_head initializer |
| 127 | * @head: &struct plist_head pointer | 141 | * @head: &struct plist_head pointer |
| 128 | * @lock: list spinlock, remembered for debugging | 142 | * @lock: spinlock protecting the list (debugging) |
| 129 | */ | 143 | */ |
| 130 | static inline void | 144 | static inline void |
| 131 | plist_head_init(struct plist_head *head, spinlock_t *lock) | 145 | plist_head_init(struct plist_head *head, spinlock_t *lock) |
| @@ -133,7 +147,24 @@ plist_head_init(struct plist_head *head, spinlock_t *lock) | |||
| 133 | INIT_LIST_HEAD(&head->prio_list); | 147 | INIT_LIST_HEAD(&head->prio_list); |
| 134 | INIT_LIST_HEAD(&head->node_list); | 148 | INIT_LIST_HEAD(&head->node_list); |
| 135 | #ifdef CONFIG_DEBUG_PI_LIST | 149 | #ifdef CONFIG_DEBUG_PI_LIST |
| 136 | head->lock = lock; | 150 | head->spinlock = lock; |
| 151 | head->rawlock = NULL; | ||
| 152 | #endif | ||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 156 | * plist_head_init_raw - dynamic struct plist_head initializer | ||
| 157 | * @head: &struct plist_head pointer | ||
| 158 | * @lock: raw_spinlock protecting the list (debugging) | ||
| 159 | */ | ||
| 160 | static inline void | ||
| 161 | plist_head_init_raw(struct plist_head *head, raw_spinlock_t *lock) | ||
| 162 | { | ||
| 163 | INIT_LIST_HEAD(&head->prio_list); | ||
| 164 | INIT_LIST_HEAD(&head->node_list); | ||
| 165 | #ifdef CONFIG_DEBUG_PI_LIST | ||
| 166 | head->rawlock = lock; | ||
| 167 | head->spinlock = NULL; | ||
| 137 | #endif | 168 | #endif |
| 138 | } | 169 | } |
| 139 | 170 | ||
diff --git a/kernel/futex.c b/kernel/futex.c index d73ef1f3e55d..6af474df17bb 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -1010,7 +1010,7 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1, | |||
| 1010 | plist_add(&q->list, &hb2->chain); | 1010 | plist_add(&q->list, &hb2->chain); |
| 1011 | q->lock_ptr = &hb2->lock; | 1011 | q->lock_ptr = &hb2->lock; |
| 1012 | #ifdef CONFIG_DEBUG_PI_LIST | 1012 | #ifdef CONFIG_DEBUG_PI_LIST |
| 1013 | q->list.plist.lock = &hb2->lock; | 1013 | q->list.plist.spinlock = &hb2->lock; |
| 1014 | #endif | 1014 | #endif |
| 1015 | } | 1015 | } |
| 1016 | get_futex_key_refs(key2); | 1016 | get_futex_key_refs(key2); |
| @@ -1046,7 +1046,7 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key, | |||
| 1046 | 1046 | ||
| 1047 | q->lock_ptr = &hb->lock; | 1047 | q->lock_ptr = &hb->lock; |
| 1048 | #ifdef CONFIG_DEBUG_PI_LIST | 1048 | #ifdef CONFIG_DEBUG_PI_LIST |
| 1049 | q->list.plist.lock = &hb->lock; | 1049 | q->list.plist.spinlock = &hb->lock; |
| 1050 | #endif | 1050 | #endif |
| 1051 | 1051 | ||
| 1052 | wake_up_state(q->task, TASK_NORMAL); | 1052 | wake_up_state(q->task, TASK_NORMAL); |
| @@ -1394,7 +1394,7 @@ static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) | |||
| 1394 | 1394 | ||
| 1395 | plist_node_init(&q->list, prio); | 1395 | plist_node_init(&q->list, prio); |
| 1396 | #ifdef CONFIG_DEBUG_PI_LIST | 1396 | #ifdef CONFIG_DEBUG_PI_LIST |
| 1397 | q->list.plist.lock = &hb->lock; | 1397 | q->list.plist.spinlock = &hb->lock; |
| 1398 | #endif | 1398 | #endif |
| 1399 | plist_add(&q->list, &hb->chain); | 1399 | plist_add(&q->list, &hb->chain); |
| 1400 | q->task = current; | 1400 | q->task = current; |
diff --git a/lib/plist.c b/lib/plist.c index d6c64a824e1d..1471988d9190 100644 --- a/lib/plist.c +++ b/lib/plist.c | |||
| @@ -54,9 +54,11 @@ static void plist_check_list(struct list_head *top) | |||
| 54 | 54 | ||
| 55 | static void plist_check_head(struct plist_head *head) | 55 | static void plist_check_head(struct plist_head *head) |
| 56 | { | 56 | { |
| 57 | WARN_ON(!head->lock); | 57 | WARN_ON(!head->rawlock && !head->spinlock); |
| 58 | if (head->lock) | 58 | if (head->rawlock) |
| 59 | WARN_ON_SMP(!spin_is_locked(head->lock)); | 59 | WARN_ON_SMP(!raw_spin_is_locked(head->rawlock)); |
| 60 | if (head->spinlock) | ||
| 61 | WARN_ON_SMP(!spin_is_locked(head->spinlock)); | ||
| 60 | plist_check_list(&head->prio_list); | 62 | plist_check_list(&head->prio_list); |
| 61 | plist_check_list(&head->node_list); | 63 | plist_check_list(&head->node_list); |
| 62 | } | 64 | } |
