Commit 5d4d8070 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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.
parent a0e259f3
/* /*
* kobject.c - library routines for handling generic kernel objects * kobject.c - library routines for handling generic kernel objects
*
* Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org>
*
*/ */
#undef DEBUG #undef DEBUG
...@@ -9,6 +12,8 @@ ...@@ -9,6 +12,8 @@
#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; static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED;
/** /**
...@@ -336,12 +341,14 @@ void kobject_unregister(struct kobject * kobj) ...@@ -336,12 +341,14 @@ 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;
spin_lock(&kobj_lock); unsigned long flags;
spin_lock_irqsave(&kobj_lock, flags);
if (kobj && atomic_read(&kobj->refcount) > 0) if (kobj && atomic_read(&kobj->refcount) > 0)
atomic_inc(&kobj->refcount); atomic_inc(&kobj->refcount);
else else
ret = NULL; ret = NULL;
spin_unlock(&kobj_lock); spin_unlock_irqrestore(&kobj_lock, flags);
return ret; return ret;
} }
...@@ -371,10 +378,15 @@ void kobject_cleanup(struct kobject * kobj) ...@@ -371,10 +378,15 @@ void kobject_cleanup(struct kobject * kobj)
void kobject_put(struct kobject * kobj) void kobject_put(struct kobject * kobj)
{ {
if (!atomic_dec_and_lock(&kobj->refcount, &kobj_lock)) unsigned long flags;
return;
spin_unlock(&kobj_lock); 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