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 | } |