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
*
* Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org>
*
*/
#undef DEBUG
......@@ -9,6 +12,8 @@
#include <linux/module.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;
/**
......@@ -336,12 +341,14 @@ void kobject_unregister(struct kobject * kobj)
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_cleanup(struct kobject * kobj)
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);
}
}
......
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