Skip to content

Commit

Permalink
debugobjects: Move printk out of db->lock critical sections
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Yang Shi <[email protected]>
Cc: "Joel Fernandes (Google)" <[email protected]>
Cc: Qian Cai <[email protected]>
Cc: Zhong Jiang <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
  • Loading branch information
Waiman-Long authored and KAGA-KOKO committed Jun 14, 2019
1 parent a7344a6 commit d5f3415
Showing 1 changed file with 39 additions and 19 deletions.
58 changes: 39 additions & 19 deletions lib/debugobjects.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -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:
Expand All @@ -637,25 +643,28 @@ 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:
ret = 0;
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
Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand All @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -937,10 +957,10 @@ static void __debug_check_no_obj_freed(const void *address, unsigned long size)

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;
Expand Down

0 comments on commit d5f3415

Please sign in to comment.