Commit 29b9acf6 authored by Patrick Mochel's avatar Patrick Mochel

[kobject] Remove kobj_lock and use lockless refcounting.

The only thing preventing this from happening earlier was the circular sysfs
registration dependency - it would need to be initialized before it was 
registered, but needed to be registered before it was initialized. 

With kobjects gone from struct filesystem_type, the dependency no longer 
exists and we don't have to special-case the possibility that a kobject will
be passed to kobject_get with a refcount == 0. 

Note that a kobject with a count of 0 in that function is still a bug, but 
one in the subsystem making the call. We should add a debugging hook to dump
the stack if it does happen. 
parent 043400bf
...@@ -17,10 +17,6 @@ ...@@ -17,10 +17,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/stat.h> #include <linux/stat.h>
/* 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;
/** /**
* populate_dir - populate directory with attributes. * populate_dir - populate directory with attributes.
* @kobj: object we're working on. * @kobj: object we're working on.
...@@ -350,14 +346,11 @@ void kobject_unregister(struct kobject * kobj) ...@@ -350,14 +346,11 @@ void kobject_unregister(struct kobject * kobj)
struct kobject * kobject_get(struct kobject * kobj) struct kobject * kobject_get(struct kobject * kobj)
{ {
struct kobject * ret = kobj; struct kobject * ret = kobj;
unsigned long flags;
spin_lock_irqsave(&kobj_lock, flags); if (kobj)
if (kobj && atomic_read(&kobj->refcount) > 0)
atomic_inc(&kobj->refcount); atomic_inc(&kobj->refcount);
else else
ret = NULL; ret = NULL;
spin_unlock_irqrestore(&kobj_lock, flags);
return ret; return ret;
} }
...@@ -387,15 +380,8 @@ void kobject_cleanup(struct kobject * kobj) ...@@ -387,15 +380,8 @@ void kobject_cleanup(struct kobject * kobj)
void kobject_put(struct kobject * kobj) void kobject_put(struct kobject * kobj)
{ {
unsigned long flags; if (atomic_dec_and_test(&kobj->refcount))
local_irq_save(flags);
if (atomic_dec_and_lock(&kobj->refcount, &kobj_lock)) {
spin_unlock_irqrestore(&kobj_lock, flags);
kobject_cleanup(kobj); kobject_cleanup(kobj);
} else {
local_irq_restore(flags);
}
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment