debugobjects: Move printk out of db->lock critical sections
The db->lock is a raw spinlock and so the lock hold time is supposed to be short. This will not be the case when printk() is being involved in some of the critical sections. In order to avoid the long hold time, in case some messages need to be printed, the debug_object_is_on_stack() and debug_print_object() calls are now moved out of those critical sections. Signed-off-by: Waiman Long <longman@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Yang Shi <yang.shi@linux.alibaba.com> Cc: "Joel Fernandes (Google)" <joel@joelfernandes.org> Cc: Qian Cai <cai@gmx.us> Cc: Zhong Jiang <zhongjiang@huawei.com> Link: https://lkml.kernel.org/r/20190520141450.7575-6-longman@redhat.com
This commit is contained in:
parent
a7344a68a7
commit
d5f34153e5
|
@ -528,6 +528,7 @@ static void
|
|||
__debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack)
|
||||
{
|
||||
enum debug_obj_state state;
|
||||
bool check_stack = false;
|
||||
struct debug_bucket *db;
|
||||
struct debug_obj *obj;
|
||||
unsigned long flags;
|
||||
|
@ -547,7 +548,7 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack)
|
|||
debug_objects_oom();
|
||||
return;
|
||||
}
|
||||
debug_object_is_on_stack(addr, onstack);
|
||||
check_stack = true;
|
||||
}
|
||||
|
||||
switch (obj->state) {
|
||||
|
@ -558,20 +559,23 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack)
|
|||
break;
|
||||
|
||||
case ODEBUG_STATE_ACTIVE:
|
||||
debug_print_object(obj, "init");
|
||||
state = obj->state;
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
debug_print_object(obj, "init");
|
||||
debug_object_fixup(descr->fixup_init, addr, state);
|
||||
return;
|
||||
|
||||
case ODEBUG_STATE_DESTROYED:
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
debug_print_object(obj, "init");
|
||||
break;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
if (check_stack)
|
||||
debug_object_is_on_stack(addr, onstack);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -629,6 +633,8 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr)
|
|||
|
||||
obj = lookup_object(addr, db);
|
||||
if (obj) {
|
||||
bool print_object = false;
|
||||
|
||||
switch (obj->state) {
|
||||
case ODEBUG_STATE_INIT:
|
||||
case ODEBUG_STATE_INACTIVE:
|
||||
|
@ -637,14 +643,14 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr)
|
|||
break;
|
||||
|
||||
case ODEBUG_STATE_ACTIVE:
|
||||
debug_print_object(obj, "activate");
|
||||
state = obj->state;
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
debug_print_object(obj, "activate");
|
||||
ret = debug_object_fixup(descr->fixup_activate, addr, state);
|
||||
return ret ? 0 : -EINVAL;
|
||||
|
||||
case ODEBUG_STATE_DESTROYED:
|
||||
debug_print_object(obj, "activate");
|
||||
print_object = true;
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
default:
|
||||
|
@ -652,10 +658,13 @@ int debug_object_activate(void *addr, struct debug_obj_descr *descr)
|
|||
break;
|
||||
}
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
if (print_object)
|
||||
debug_print_object(obj, "activate");
|
||||
return ret;
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
||||
/*
|
||||
* We are here when a static object is activated. We
|
||||
* let the type specific code confirm whether this is
|
||||
|
@ -687,6 +696,7 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr)
|
|||
struct debug_bucket *db;
|
||||
struct debug_obj *obj;
|
||||
unsigned long flags;
|
||||
bool print_object = false;
|
||||
|
||||
if (!debug_objects_enabled)
|
||||
return;
|
||||
|
@ -704,24 +714,27 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr)
|
|||
if (!obj->astate)
|
||||
obj->state = ODEBUG_STATE_INACTIVE;
|
||||
else
|
||||
debug_print_object(obj, "deactivate");
|
||||
print_object = true;
|
||||
break;
|
||||
|
||||
case ODEBUG_STATE_DESTROYED:
|
||||
debug_print_object(obj, "deactivate");
|
||||
print_object = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
if (!obj) {
|
||||
struct debug_obj o = { .object = addr,
|
||||
.state = ODEBUG_STATE_NOTAVAILABLE,
|
||||
.descr = descr };
|
||||
|
||||
debug_print_object(&o, "deactivate");
|
||||
} else if (print_object) {
|
||||
debug_print_object(obj, "deactivate");
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(debug_object_deactivate);
|
||||
|
||||
|
@ -736,6 +749,7 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr)
|
|||
struct debug_bucket *db;
|
||||
struct debug_obj *obj;
|
||||
unsigned long flags;
|
||||
bool print_object = false;
|
||||
|
||||
if (!debug_objects_enabled)
|
||||
return;
|
||||
|
@ -755,20 +769,22 @@ void debug_object_destroy(void *addr, struct debug_obj_descr *descr)
|
|||
obj->state = ODEBUG_STATE_DESTROYED;
|
||||
break;
|
||||
case ODEBUG_STATE_ACTIVE:
|
||||
debug_print_object(obj, "destroy");
|
||||
state = obj->state;
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
debug_print_object(obj, "destroy");
|
||||
debug_object_fixup(descr->fixup_destroy, addr, state);
|
||||
return;
|
||||
|
||||
case ODEBUG_STATE_DESTROYED:
|
||||
debug_print_object(obj, "destroy");
|
||||
print_object = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
out_unlock:
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
if (print_object)
|
||||
debug_print_object(obj, "destroy");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(debug_object_destroy);
|
||||
|
||||
|
@ -797,9 +813,9 @@ void debug_object_free(void *addr, struct debug_obj_descr *descr)
|
|||
|
||||
switch (obj->state) {
|
||||
case ODEBUG_STATE_ACTIVE:
|
||||
debug_print_object(obj, "free");
|
||||
state = obj->state;
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
debug_print_object(obj, "free");
|
||||
debug_object_fixup(descr->fixup_free, addr, state);
|
||||
return;
|
||||
default:
|
||||
|
@ -872,6 +888,7 @@ debug_object_active_state(void *addr, struct debug_obj_descr *descr,
|
|||
struct debug_bucket *db;
|
||||
struct debug_obj *obj;
|
||||
unsigned long flags;
|
||||
bool print_object = false;
|
||||
|
||||
if (!debug_objects_enabled)
|
||||
return;
|
||||
|
@ -887,22 +904,25 @@ debug_object_active_state(void *addr, struct debug_obj_descr *descr,
|
|||
if (obj->astate == expect)
|
||||
obj->astate = next;
|
||||
else
|
||||
debug_print_object(obj, "active_state");
|
||||
print_object = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
debug_print_object(obj, "active_state");
|
||||
print_object = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
if (!obj) {
|
||||
struct debug_obj o = { .object = addr,
|
||||
.state = ODEBUG_STATE_NOTAVAILABLE,
|
||||
.descr = descr };
|
||||
|
||||
debug_print_object(&o, "active_state");
|
||||
} else if (print_object) {
|
||||
debug_print_object(obj, "active_state");
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(debug_object_active_state);
|
||||
|
||||
|
@ -937,10 +957,10 @@ repeat:
|
|||
|
||||
switch (obj->state) {
|
||||
case ODEBUG_STATE_ACTIVE:
|
||||
debug_print_object(obj, "free");
|
||||
descr = obj->descr;
|
||||
state = obj->state;
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
debug_print_object(obj, "free");
|
||||
debug_object_fixup(descr->fixup_free,
|
||||
(void *) oaddr, state);
|
||||
goto repeat;
|
||||
|
|
Loading…
Reference in New Issue