aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/plist.h43
-rw-r--r--kernel/futex.c6
-rw-r--r--lib/plist.c8
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 */
130static inline void 144static inline void
131plist_head_init(struct plist_head *head, spinlock_t *lock) 145plist_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 */
160static inline void
161plist_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
55static void plist_check_head(struct plist_head *head) 55static 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}