aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugobjects.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/debugobjects.c')
-rw-r--r--lib/debugobjects.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 85b18d79be89..e3ab374e1334 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -112,6 +112,7 @@ static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b)
112 112
113/* 113/*
114 * Allocate a new object. If the pool is empty, switch off the debugger. 114 * Allocate a new object. If the pool is empty, switch off the debugger.
115 * Must be called with interrupts disabled.
115 */ 116 */
116static struct debug_obj * 117static struct debug_obj *
117alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr) 118alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
@@ -148,17 +149,18 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
148static void free_object(struct debug_obj *obj) 149static void free_object(struct debug_obj *obj)
149{ 150{
150 unsigned long idx = (unsigned long)(obj - obj_static_pool); 151 unsigned long idx = (unsigned long)(obj - obj_static_pool);
152 unsigned long flags;
151 153
152 if (obj_pool_free < ODEBUG_POOL_SIZE || idx < ODEBUG_POOL_SIZE) { 154 if (obj_pool_free < ODEBUG_POOL_SIZE || idx < ODEBUG_POOL_SIZE) {
153 spin_lock(&pool_lock); 155 spin_lock_irqsave(&pool_lock, flags);
154 hlist_add_head(&obj->node, &obj_pool); 156 hlist_add_head(&obj->node, &obj_pool);
155 obj_pool_free++; 157 obj_pool_free++;
156 obj_pool_used--; 158 obj_pool_used--;
157 spin_unlock(&pool_lock); 159 spin_unlock_irqrestore(&pool_lock, flags);
158 } else { 160 } else {
159 spin_lock(&pool_lock); 161 spin_lock_irqsave(&pool_lock, flags);
160 obj_pool_used--; 162 obj_pool_used--;
161 spin_unlock(&pool_lock); 163 spin_unlock_irqrestore(&pool_lock, flags);
162 kmem_cache_free(obj_cache, obj); 164 kmem_cache_free(obj_cache, obj);
163 } 165 }
164} 166}
@@ -171,6 +173,7 @@ static void debug_objects_oom(void)
171{ 173{
172 struct debug_bucket *db = obj_hash; 174 struct debug_bucket *db = obj_hash;
173 struct hlist_node *node, *tmp; 175 struct hlist_node *node, *tmp;
176 HLIST_HEAD(freelist);
174 struct debug_obj *obj; 177 struct debug_obj *obj;
175 unsigned long flags; 178 unsigned long flags;
176 int i; 179 int i;
@@ -179,11 +182,14 @@ static void debug_objects_oom(void)
179 182
180 for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) { 183 for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) {
181 spin_lock_irqsave(&db->lock, flags); 184 spin_lock_irqsave(&db->lock, flags);
182 hlist_for_each_entry_safe(obj, node, tmp, &db->list, node) { 185 hlist_move_list(&db->list, &freelist);
186 spin_unlock_irqrestore(&db->lock, flags);
187
188 /* Now free them */
189 hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) {
183 hlist_del(&obj->node); 190 hlist_del(&obj->node);
184 free_object(obj); 191 free_object(obj);
185 } 192 }
186 spin_unlock_irqrestore(&db->lock, flags);
187 } 193 }
188} 194}
189 195
@@ -205,9 +211,8 @@ static void debug_print_object(struct debug_obj *obj, char *msg)
205 211
206 if (limit < 5 && obj->descr != descr_test) { 212 if (limit < 5 && obj->descr != descr_test) {
207 limit++; 213 limit++;
208 printk(KERN_ERR "ODEBUG: %s %s object type: %s\n", msg, 214 WARN(1, KERN_ERR "ODEBUG: %s %s object type: %s\n", msg,
209 obj_states[obj->state], obj->descr->name); 215 obj_states[obj->state], obj->descr->name);
210 WARN_ON(1);
211 } 216 }
212 debug_objects_warnings++; 217 debug_objects_warnings++;
213} 218}
@@ -226,15 +231,13 @@ debug_object_fixup(int (*fixup)(void *addr, enum debug_obj_state state),
226 231
227static void debug_object_is_on_stack(void *addr, int onstack) 232static void debug_object_is_on_stack(void *addr, int onstack)
228{ 233{
229 void *stack = current->stack;
230 int is_on_stack; 234 int is_on_stack;
231 static int limit; 235 static int limit;
232 236
233 if (limit > 4) 237 if (limit > 4)
234 return; 238 return;
235 239
236 is_on_stack = (addr >= stack && addr < (stack + THREAD_SIZE)); 240 is_on_stack = object_is_on_stack(addr);
237
238 if (is_on_stack == onstack) 241 if (is_on_stack == onstack)
239 return; 242 return;
240 243
@@ -501,8 +504,9 @@ void debug_object_free(void *addr, struct debug_obj_descr *descr)
501 return; 504 return;
502 default: 505 default:
503 hlist_del(&obj->node); 506 hlist_del(&obj->node);
507 spin_unlock_irqrestore(&db->lock, flags);
504 free_object(obj); 508 free_object(obj);
505 break; 509 return;
506 } 510 }
507out_unlock: 511out_unlock:
508 spin_unlock_irqrestore(&db->lock, flags); 512 spin_unlock_irqrestore(&db->lock, flags);
@@ -513,6 +517,7 @@ static void __debug_check_no_obj_freed(const void *address, unsigned long size)
513{ 517{
514 unsigned long flags, oaddr, saddr, eaddr, paddr, chunks; 518 unsigned long flags, oaddr, saddr, eaddr, paddr, chunks;
515 struct hlist_node *node, *tmp; 519 struct hlist_node *node, *tmp;
520 HLIST_HEAD(freelist);
516 struct debug_obj_descr *descr; 521 struct debug_obj_descr *descr;
517 enum debug_obj_state state; 522 enum debug_obj_state state;
518 struct debug_bucket *db; 523 struct debug_bucket *db;
@@ -548,11 +553,18 @@ repeat:
548 goto repeat; 553 goto repeat;
549 default: 554 default:
550 hlist_del(&obj->node); 555 hlist_del(&obj->node);
551 free_object(obj); 556 hlist_add_head(&obj->node, &freelist);
552 break; 557 break;
553 } 558 }
554 } 559 }
555 spin_unlock_irqrestore(&db->lock, flags); 560 spin_unlock_irqrestore(&db->lock, flags);
561
562 /* Now free them */
563 hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) {
564 hlist_del(&obj->node);
565 free_object(obj);
566 }
567
556 if (cnt > debug_objects_maxchain) 568 if (cnt > debug_objects_maxchain)
557 debug_objects_maxchain = cnt; 569 debug_objects_maxchain = cnt;
558 } 570 }
@@ -735,26 +747,22 @@ check_results(void *addr, enum debug_obj_state state, int fixups, int warnings)
735 747
736 obj = lookup_object(addr, db); 748 obj = lookup_object(addr, db);
737 if (!obj && state != ODEBUG_STATE_NONE) { 749 if (!obj && state != ODEBUG_STATE_NONE) {
738 printk(KERN_ERR "ODEBUG: selftest object not found\n"); 750 WARN(1, KERN_ERR "ODEBUG: selftest object not found\n");
739 WARN_ON(1);
740 goto out; 751 goto out;
741 } 752 }
742 if (obj && obj->state != state) { 753 if (obj && obj->state != state) {
743 printk(KERN_ERR "ODEBUG: selftest wrong state: %d != %d\n", 754 WARN(1, KERN_ERR "ODEBUG: selftest wrong state: %d != %d\n",
744 obj->state, state); 755 obj->state, state);
745 WARN_ON(1);
746 goto out; 756 goto out;
747 } 757 }
748 if (fixups != debug_objects_fixups) { 758 if (fixups != debug_objects_fixups) {
749 printk(KERN_ERR "ODEBUG: selftest fixups failed %d != %d\n", 759 WARN(1, KERN_ERR "ODEBUG: selftest fixups failed %d != %d\n",
750 fixups, debug_objects_fixups); 760 fixups, debug_objects_fixups);
751 WARN_ON(1);
752 goto out; 761 goto out;
753 } 762 }
754 if (warnings != debug_objects_warnings) { 763 if (warnings != debug_objects_warnings) {
755 printk(KERN_ERR "ODEBUG: selftest warnings failed %d != %d\n", 764 WARN(1, KERN_ERR "ODEBUG: selftest warnings failed %d != %d\n",
756 warnings, debug_objects_warnings); 765 warnings, debug_objects_warnings);
757 WARN_ON(1);
758 goto out; 766 goto out;
759 } 767 }
760 res = 0; 768 res = 0;