ChangeSet 1.1156, 2003/04/28 22:27:58-07:00, greg@kroah.com kobject: kobj_lock needs to be grabed using spinlock_irq This is because some subsystems (cough, usb...) can grab a kobject from irq context. This lock can be completely removed once the sysfs_init() code is cleaned up. Patch originally by Andrew Morton. lib/kobject.c | 24 ++++++++++++++++++------ 1 files changed, 18 insertions(+), 6 deletions(-) diff -Nru a/lib/kobject.c b/lib/kobject.c --- a/lib/kobject.c Tue Apr 29 09:48:29 2003 +++ b/lib/kobject.c Tue Apr 29 09:48:29 2003 @@ -1,5 +1,8 @@ /* * kobject.c - library routines for handling generic kernel objects + * + * Copyright (c) 2002-2003 Patrick Mochel + * */ #undef DEBUG @@ -9,6 +12,8 @@ #include #include +/* This lock can be removed entirely when the sysfs_init() code is cleaned up + * to not try to reference itself before it is initialized. */ static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED; /** @@ -336,12 +341,14 @@ struct kobject * kobject_get(struct kobject * kobj) { struct kobject * ret = kobj; - spin_lock(&kobj_lock); + unsigned long flags; + + spin_lock_irqsave(&kobj_lock, flags); if (kobj && atomic_read(&kobj->refcount) > 0) atomic_inc(&kobj->refcount); else ret = NULL; - spin_unlock(&kobj_lock); + spin_unlock_irqrestore(&kobj_lock, flags); return ret; } @@ -371,10 +378,15 @@ void kobject_put(struct kobject * kobj) { - if (!atomic_dec_and_lock(&kobj->refcount, &kobj_lock)) - return; - spin_unlock(&kobj_lock); - kobject_cleanup(kobj); + unsigned long flags; + + local_irq_save(flags); + if (atomic_dec_and_lock(&kobj->refcount, &kobj_lock)) { + spin_unlock_irqrestore(&kobj_lock, flags); + kobject_cleanup(kobj); + } else { + local_irq_restore(flags); + } }