debugobjects: Make debug_object_activate() return status
In order to better respond to things like duplicate invocations of call_rcu(), RCU needs to see the status of a call to debug_object_activate(). This would allow RCU to leak the callback in order to avoid adding freelist-reuse mischief to the duplicate invoations. This commit therefore makes debug_object_activate() return status, zero for success and -EINVAL for failure. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Sedat Dilek <sedat.dilek@gmail.com> Cc: Davidlohr Bueso <davidlohr.bueso@hp.com> Cc: Rik van Riel <riel@surriel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Tested-by: Sedat Dilek <sedat.dilek@gmail.com> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
This commit is contained in:
parent
15100df81f
commit
b778ae2536
|
@ -63,7 +63,7 @@ struct debug_obj_descr {
|
|||
extern void debug_object_init (void *addr, struct debug_obj_descr *descr);
|
||||
extern void
|
||||
debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr);
|
||||
extern void debug_object_activate (void *addr, struct debug_obj_descr *descr);
|
||||
extern int debug_object_activate (void *addr, struct debug_obj_descr *descr);
|
||||
extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr);
|
||||
extern void debug_object_destroy (void *addr, struct debug_obj_descr *descr);
|
||||
extern void debug_object_free (void *addr, struct debug_obj_descr *descr);
|
||||
|
@ -85,8 +85,8 @@ static inline void
|
|||
debug_object_init (void *addr, struct debug_obj_descr *descr) { }
|
||||
static inline void
|
||||
debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr) { }
|
||||
static inline void
|
||||
debug_object_activate (void *addr, struct debug_obj_descr *descr) { }
|
||||
static inline int
|
||||
debug_object_activate (void *addr, struct debug_obj_descr *descr) { return 0; }
|
||||
static inline void
|
||||
debug_object_deactivate(void *addr, struct debug_obj_descr *descr) { }
|
||||
static inline void
|
||||
|
|
|
@ -381,19 +381,21 @@ void debug_object_init_on_stack(void *addr, struct debug_obj_descr *descr)
|
|||
* debug_object_activate - debug checks when an object is activated
|
||||
* @addr: address of the object
|
||||
* @descr: pointer to an object specific debug description structure
|
||||
* Returns 0 for success, -EINVAL for check failed.
|
||||
*/
|
||||
void debug_object_activate(void *addr, struct debug_obj_descr *descr)
|
||||
int debug_object_activate(void *addr, struct debug_obj_descr *descr)
|
||||
{
|
||||
enum debug_obj_state state;
|
||||
struct debug_bucket *db;
|
||||
struct debug_obj *obj;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
struct debug_obj o = { .object = addr,
|
||||
.state = ODEBUG_STATE_NOTAVAILABLE,
|
||||
.descr = descr };
|
||||
|
||||
if (!debug_objects_enabled)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
db = get_bucket((unsigned long) addr);
|
||||
|
||||
|
@ -405,23 +407,26 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr)
|
|||
case ODEBUG_STATE_INIT:
|
||||
case ODEBUG_STATE_INACTIVE:
|
||||
obj->state = ODEBUG_STATE_ACTIVE;
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case ODEBUG_STATE_ACTIVE:
|
||||
debug_print_object(obj, "activate");
|
||||
state = obj->state;
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
debug_object_fixup(descr->fixup_activate, addr, state);
|
||||
return;
|
||||
ret = debug_object_fixup(descr->fixup_activate, addr, state);
|
||||
return ret ? -EINVAL : 0;
|
||||
|
||||
case ODEBUG_STATE_DESTROYED:
|
||||
debug_print_object(obj, "activate");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
raw_spin_unlock_irqrestore(&db->lock, flags);
|
||||
|
@ -431,8 +436,11 @@ void debug_object_activate(void *addr, struct debug_obj_descr *descr)
|
|||
* true or not.
|
||||
*/
|
||||
if (debug_object_fixup(descr->fixup_activate, addr,
|
||||
ODEBUG_STATE_NOTAVAILABLE))
|
||||
ODEBUG_STATE_NOTAVAILABLE)) {
|
||||
debug_print_object(&o, "activate");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue