idle: Remove GENERIC_IDLE_LOOP config switch
[linux-3.10.git] / lib / debugobjects.c
index b7a5305..37061ed 100644 (file)
@@ -79,30 +79,29 @@ static const char *obj_states[ODEBUG_STATE_MAX] = {
        [ODEBUG_STATE_NOTAVAILABLE]     = "not available",
 };
 
-static int fill_pool(void)
+static void fill_pool(void)
 {
        gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
        struct debug_obj *new;
        unsigned long flags;
 
        if (likely(obj_pool_free >= ODEBUG_POOL_MIN_LEVEL))
-               return obj_pool_free;
+               return;
 
        if (unlikely(!obj_cache))
-               return obj_pool_free;
+               return;
 
        while (obj_pool_free < ODEBUG_POOL_MIN_LEVEL) {
 
                new = kmem_cache_zalloc(obj_cache, gfp);
                if (!new)
-                       return obj_pool_free;
+                       return;
 
                raw_spin_lock_irqsave(&pool_lock, flags);
                hlist_add_head(&new->node, &obj_pool);
                obj_pool_free++;
                raw_spin_unlock_irqrestore(&pool_lock, flags);
        }
-       return obj_pool_free;
 }
 
 /*
@@ -110,11 +109,10 @@ static int fill_pool(void)
  */
 static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b)
 {
-       struct hlist_node *node;
        struct debug_obj *obj;
        int cnt = 0;
 
-       hlist_for_each_entry(obj, node, &b->list, node) {
+       hlist_for_each_entry(obj, &b->list, node) {
                cnt++;
                if (obj->object == addr)
                        return obj;
@@ -214,7 +212,7 @@ static void free_object(struct debug_obj *obj)
 static void debug_objects_oom(void)
 {
        struct debug_bucket *db = obj_hash;
-       struct hlist_node *node, *tmp;
+       struct hlist_node *tmp;
        HLIST_HEAD(freelist);
        struct debug_obj *obj;
        unsigned long flags;
@@ -228,7 +226,7 @@ static void debug_objects_oom(void)
                raw_spin_unlock_irqrestore(&db->lock, flags);
 
                /* Now free them */
-               hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) {
+               hlist_for_each_entry_safe(obj, tmp, &freelist, node) {
                        hlist_del(&obj->node);
                        free_object(obj);
                }
@@ -571,6 +569,44 @@ out_unlock:
 }
 
 /**
+ * debug_object_assert_init - debug checks when object should be init-ed
+ * @addr:      address of the object
+ * @descr:     pointer to an object specific debug description structure
+ */
+void debug_object_assert_init(void *addr, struct debug_obj_descr *descr)
+{
+       struct debug_bucket *db;
+       struct debug_obj *obj;
+       unsigned long flags;
+
+       if (!debug_objects_enabled)
+               return;
+
+       db = get_bucket((unsigned long) addr);
+
+       raw_spin_lock_irqsave(&db->lock, flags);
+
+       obj = lookup_object(addr, db);
+       if (!obj) {
+               struct debug_obj o = { .object = addr,
+                                      .state = ODEBUG_STATE_NOTAVAILABLE,
+                                      .descr = descr };
+
+               raw_spin_unlock_irqrestore(&db->lock, flags);
+               /*
+                * Maybe the object is static.  Let the type specific
+                * code decide what to do.
+                */
+               if (debug_object_fixup(descr->fixup_assert_init, addr,
+                                      ODEBUG_STATE_NOTAVAILABLE))
+                       debug_print_object(&o, "assert_init");
+               return;
+       }
+
+       raw_spin_unlock_irqrestore(&db->lock, flags);
+}
+
+/**
  * debug_object_active_state - debug checks object usage state machine
  * @addr:      address of the object
  * @descr:     pointer to an object specific debug description structure
@@ -621,7 +657,7 @@ debug_object_active_state(void *addr, struct debug_obj_descr *descr,
 static void __debug_check_no_obj_freed(const void *address, unsigned long size)
 {
        unsigned long flags, oaddr, saddr, eaddr, paddr, chunks;
-       struct hlist_node *node, *tmp;
+       struct hlist_node *tmp;
        HLIST_HEAD(freelist);
        struct debug_obj_descr *descr;
        enum debug_obj_state state;
@@ -641,7 +677,7 @@ static void __debug_check_no_obj_freed(const void *address, unsigned long size)
 repeat:
                cnt = 0;
                raw_spin_lock_irqsave(&db->lock, flags);
-               hlist_for_each_entry_safe(obj, node, tmp, &db->list, node) {
+               hlist_for_each_entry_safe(obj, tmp, &db->list, node) {
                        cnt++;
                        oaddr = (unsigned long) obj->object;
                        if (oaddr < saddr || oaddr >= eaddr)
@@ -665,7 +701,7 @@ repeat:
                raw_spin_unlock_irqrestore(&db->lock, flags);
 
                /* Now free them */
-               hlist_for_each_entry_safe(obj, node, tmp, &freelist, node) {
+               hlist_for_each_entry_safe(obj, tmp, &freelist, node) {
                        hlist_del(&obj->node);
                        free_object(obj);
                }
@@ -780,17 +816,9 @@ static int __init fixup_activate(void *addr, enum debug_obj_state state)
                if (obj->static_init == 1) {
                        debug_object_init(obj, &descr_type_test);
                        debug_object_activate(obj, &descr_type_test);
-                       /*
-                        * Real code should return 0 here ! This is
-                        * not a fixup of some bad behaviour. We
-                        * merily call the debug_init function to keep
-                        * track of the object.
-                        */
-                       return 1;
-               } else {
-                       /* Real code needs to emit a warning here */
+                       return 0;
                }
-               return 0;
+               return 1;
 
        case ODEBUG_STATE_ACTIVE:
                debug_object_deactivate(obj, &descr_type_test);
@@ -929,7 +957,7 @@ static void __init debug_objects_selftest(void)
 
        obj.static_init = 1;
        debug_object_activate(&obj, &descr_type_test);
-       if (check_results(&obj, ODEBUG_STATE_ACTIVE, ++fixups, warnings))
+       if (check_results(&obj, ODEBUG_STATE_ACTIVE, fixups, warnings))
                goto out;
        debug_object_init(&obj, &descr_type_test);
        if (check_results(&obj, ODEBUG_STATE_INIT, ++fixups, ++warnings))
@@ -984,7 +1012,7 @@ void __init debug_objects_early_init(void)
 static int __init debug_objects_replace_static_objects(void)
 {
        struct debug_bucket *db = obj_hash;
-       struct hlist_node *node, *tmp;
+       struct hlist_node *tmp;
        struct debug_obj *obj, *new;
        HLIST_HEAD(objects);
        int i, cnt = 0;
@@ -1004,7 +1032,7 @@ static int __init debug_objects_replace_static_objects(void)
        local_irq_disable();
 
        /* Remove the statically allocated objects from the pool */
-       hlist_for_each_entry_safe(obj, node, tmp, &obj_pool, node)
+       hlist_for_each_entry_safe(obj, tmp, &obj_pool, node)
                hlist_del(&obj->node);
        /* Move the allocated objects to the pool */
        hlist_move_list(&objects, &obj_pool);
@@ -1013,7 +1041,7 @@ static int __init debug_objects_replace_static_objects(void)
        for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) {
                hlist_move_list(&db->list, &objects);
 
-               hlist_for_each_entry(obj, node, &objects, node) {
+               hlist_for_each_entry(obj, &objects, node) {
                        new = hlist_entry(obj_pool.first, typeof(*obj), node);
                        hlist_del(&new->node);
                        /* copy object data */
@@ -1022,13 +1050,13 @@ static int __init debug_objects_replace_static_objects(void)
                        cnt++;
                }
        }
+       local_irq_enable();
 
        printk(KERN_DEBUG "ODEBUG: %d of %d active objects replaced\n", cnt,
               obj_pool_used);
-       local_irq_enable();
        return 0;
 free:
-       hlist_for_each_entry_safe(obj, node, tmp, &objects, node) {
+       hlist_for_each_entry_safe(obj, tmp, &objects, node) {
                hlist_del(&obj->node);
                kmem_cache_free(obj_cache, obj);
        }