linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][-mm] reclassify sg_sysfs_class for lockdep
@ 2008-05-27 10:10 Dave Young
  2008-05-28 14:40 ` James Bottomley
  2008-05-28 14:49 ` Matthew Wilcox
  0 siblings, 2 replies; 6+ messages in thread
From: Dave Young @ 2008-05-27 10:10 UTC (permalink / raw)
  To: akpm; +Cc: greg, matthew, kay.sievers, linux-kernel, linux-scsi

As register sg_interface, the sg_add will be called, which then will
add device to sg_sysfs_class. This will cause lockdep warning,
please see following email

In this case the locks are from diffrent classi, one is sdev_class,
another is sg_sysfs_class 

Here reclassify the sg_sysfs_class for lockdep

Date: Wed, 14 May 2008 08:56:39 -0700
From: Greg KH <greg@kroah.com>
To: Andrew Morton <akpm@linux-foundation.org>,
	Dave Young <hidave.darkstar@gmail.com>
Cc: linux-scsi@vger.kernel.org, Kay Sievers <kay.sievers@vrfy.org>
Subject: Re: lockdep whine in 2.6.26-rc2-mm1
Message-ID: <20080514155639.GB28594@kroah.com>
References: <20080514000933.56adc131.akpm@linux-foundation.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <20080514000933.56adc131.akpm@linux-foundation.org>
User-Agent: Mutt/1.5.16 (2007-06-09)


On Wed, May 14, 2008 at 12:09:33AM -0700, Andrew Morton wrote:
> 
> =============================================
> [ INFO: possible recursive locking detected ]
> 2.6.26-rc2-mm1 #15
> ---------------------------------------------
> modprobe/942 is trying to acquire lock:
>  (&cls->mutex){--..}, at: [<ffffffff811b431e>] device_add+0x43d/0x57a
> 
> but task is already holding lock:
>  (&cls->mutex){--..}, at: [<ffffffff811b6787>] class_interface_register+0x48/0xbd
> 
> other info that might help us debug this:
> 1 lock held by modprobe/942:
>  #0:  (&cls->mutex){--..}, at: [<ffffffff811b6787>] class_interface_register+0x48/0xbd
> 
> stack backtrace:
> Pid: 942, comm: modprobe Not tainted 2.6.26-rc2-mm1 #15
> 
> Call Trace:
>  [<ffffffff81056be1>] __lock_acquire+0x90d/0xc50
>  [<ffffffff8100c50f>] ? restore_args+0x0/0x30
>  [<ffffffff811b431e>] ? device_add+0x43d/0x57a
>  [<ffffffff81057276>] lock_acquire+0x91/0xb7
>  [<ffffffff811b431e>] ? device_add+0x43d/0x57a
>  [<ffffffff812b23ab>] mutex_lock_nested+0xf2/0x278
>  [<ffffffff811b431e>] ? device_add+0x43d/0x57a
>  [<ffffffff812b3acd>] ? _spin_unlock+0x23/0x28
>  [<ffffffff811b431e>] device_add+0x43d/0x57a
>  [<ffffffff811b4471>] device_register+0x16/0x1b
>  [<ffffffff811b4555>] device_create+0xdf/0x112
>  [<ffffffff81055fdc>] ? trace_hardirqs_on+0xd/0xf
>  [<ffffffff81055fdc>] ? trace_hardirqs_on+0xd/0xf
>  [<ffffffff812b1fe1>] ? mutex_unlock+0x9/0xb
>  [<ffffffff811b79b7>] ? kobj_map+0x113/0x124
>  [<ffffffff810ac0f5>] ? exact_lock+0x0/0x14
>  [<ffffffff810abd09>] ? exact_match+0x0/0x9
>  [<ffffffffa00ec448>] :sg:sg_add+0x2a3/0x3bd
>  [<ffffffff811b67b6>] class_interface_register+0x77/0xbd
>  [<ffffffffa005d869>] :scsi_mod:scsi_register_interface+0x11/0x13
>  [<ffffffffa00d50a3>] :sg:init_sg+0xa3/0x155
>  [<ffffffff8105ea8f>] sys_init_module+0x1823/0x197a
>  [<ffffffff810c45bc>] ? seq_release+0x0/0x56
>  [<ffffffff8100bebb>] system_call_after_swapgs+0x7b/0x80

Signed-off-by: Dave Young <hidave.darkstar@gmail.com>

---
drivers/scsi/sg.c |    6 ++++++
1 file changed, 6 insertions(+)

diff -upr linux/drivers/scsi/sg.c linux.new/drivers/scsi/sg.c
--- linux/drivers/scsi/sg.c	2008-05-27 17:09:42.000000000 +0800
+++ linux.new/drivers/scsi/sg.c	2008-05-27 17:09:51.000000000 +0800
@@ -49,6 +49,7 @@ static int sg_version_num = 30534;	/* 2 
 #include <linux/delay.h>
 #include <linux/scatterlist.h>
 #include <linux/blktrace_api.h>
+#include <linux/lockdep.h>
 
 #include "scsi.h"
 #include <scsi/scsi_dbg.h>
@@ -67,6 +68,8 @@ static int sg_proc_init(void);
 static void sg_proc_cleanup(void);
 #endif
 
+static struct lock_class_key sg_class_key;
+
 #define SG_ALLOW_DIO_DEF 0
 #define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
 
@@ -1579,6 +1582,9 @@ init_sg(void)
 		rc = PTR_ERR(sg_sysfs_class);
 		goto err_out;
         }
+
+	lockdep_set_class_and_name(&sg_sysfs_class->mutex, &sg_class_key,
+						sg_sysfs_class->name);
 	sg_sysfs_valid = 1;
 	rc = scsi_register_interface(&sg_interface);
 	if (0 == rc) {

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][-mm] reclassify sg_sysfs_class for lockdep
  2008-05-27 10:10 [PATCH][-mm] reclassify sg_sysfs_class for lockdep Dave Young
@ 2008-05-28 14:40 ` James Bottomley
  2008-05-29  0:45   ` Dave Young
  2008-05-28 14:49 ` Matthew Wilcox
  1 sibling, 1 reply; 6+ messages in thread
From: James Bottomley @ 2008-05-28 14:40 UTC (permalink / raw)
  To: Dave Young; +Cc: akpm, greg, matthew, kay.sievers, linux-kernel, linux-scsi

On Tue, 2008-05-27 at 18:10 +0800, Dave Young wrote:
> As register sg_interface, the sg_add will be called, which then will
> add device to sg_sysfs_class. This will cause lockdep warning,
> please see following email
> 
> In this case the locks are from diffrent classi, one is sdev_class,
> another is sg_sysfs_class 
> 
> Here reclassify the sg_sysfs_class for lockdep

This isn't really a generic solution, is it?  It only works because we
currently only have two users of the interface functions, so if we
reclassify one they look separate to lockdep.  It will fall over again
if we ever get another one.

Surely the correct fix is to initialise lockdep for the mutex the same
way we did for the semaphore in class_register() (which does exactly the
same locking without triggering lockdep)?  That way we'll also fix the
problem for other conversions of semaphore->mutex.

James

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][-mm] reclassify sg_sysfs_class for lockdep
  2008-05-27 10:10 [PATCH][-mm] reclassify sg_sysfs_class for lockdep Dave Young
  2008-05-28 14:40 ` James Bottomley
@ 2008-05-28 14:49 ` Matthew Wilcox
  2008-05-28 19:18   ` Andrew Morton
  1 sibling, 1 reply; 6+ messages in thread
From: Matthew Wilcox @ 2008-05-28 14:49 UTC (permalink / raw)
  To: Dave Young; +Cc: akpm, greg, kay.sievers, linux-kernel, linux-scsi

On Tue, May 27, 2008 at 06:10:09PM +0800, Dave Young wrote:
> As register sg_interface, the sg_add will be called, which then will
> add device to sg_sysfs_class. This will cause lockdep warning,
> please see following email
> 
> In this case the locks are from diffrent classi, one is sdev_class,
> another is sg_sysfs_class 
> 
> Here reclassify the sg_sysfs_class for lockdep

Look, you've been told how to do this properly.  Send me the patch that
does the mutex conversion and I'll do a patch on top of that.  I have no
inclination to go wading in the cesspool of patches that is mm trying to
find yours.

-- 
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][-mm] reclassify sg_sysfs_class for lockdep
  2008-05-28 14:49 ` Matthew Wilcox
@ 2008-05-28 19:18   ` Andrew Morton
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Morton @ 2008-05-28 19:18 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: hidave.darkstar, greg, kay.sievers, linux-kernel, linux-scsi

On Wed, 28 May 2008 08:49:43 -0600
Matthew Wilcox <matthew@wil.cx> wrote:

> On Tue, May 27, 2008 at 06:10:09PM +0800, Dave Young wrote:
> > As register sg_interface, the sg_add will be called, which then will
> > add device to sg_sysfs_class. This will cause lockdep warning,
> > please see following email
> > 
> > In this case the locks are from diffrent classi, one is sdev_class,
> > another is sg_sysfs_class 
> > 
> > Here reclassify the sg_sysfs_class for lockdep
> 
> Look, you've been told how to do this properly.  Send me the patch that
> does the mutex conversion and I'll do a patch on top of that.

Below.

>  I have no
> inclination to go wading in the cesspool of patches that is mm trying to
> find yours.

Feel free to identify the cessful patches so they can be fixed or dropped.


From: Dave Young <hidave.darkstar@gmail.com>

The class_device is already removed, so do the class->sem to mutex conversion.

Signed-off-by: Dave Young <hidave.darkstar@gmail.com>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 drivers/base/class.c   |   22 +++++++++++-----------
 drivers/base/core.c    |    9 ++++-----
 include/linux/device.h |    3 ++-
 3 files changed, 17 insertions(+), 17 deletions(-)

diff -puN drivers/base/class.c~struct-class-sem-to-mutex-converting drivers/base/class.c
--- a/drivers/base/class.c~struct-class-sem-to-mutex-converting
+++ a/drivers/base/class.c
@@ -143,7 +143,7 @@ int class_register(struct class *cls)
 	INIT_LIST_HEAD(&cls->devices);
 	INIT_LIST_HEAD(&cls->interfaces);
 	kset_init(&cls->class_dirs);
-	init_MUTEX(&cls->sem);
+	mutex_init(&cls->mutex);
 	error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name);
 	if (error)
 		return error;
@@ -268,7 +268,7 @@ char *make_class_name(const char *name, 
  * We check the return of @fn each time. If it returns anything
  * other than 0, we break out and return that value.
  *
- * Note, we hold class->sem in this function, so it can not be
+ * Note, we hold class->mutex in this function, so it can not be
  * re-acquired in @fn, otherwise it will self-deadlocking. For
  * example, calls to add or remove class members would be verboten.
  */
@@ -280,7 +280,7 @@ int class_for_each_device(struct class *
 
 	if (!class)
 		return -EINVAL;
-	down(&class->sem);
+	mutex_lock(&class->mutex);
 	list_for_each_entry(dev, &class->devices, node) {
 		if (start) {
 			if (start == dev)
@@ -293,7 +293,7 @@ int class_for_each_device(struct class *
 		if (error)
 			break;
 	}
-	up(&class->sem);
+	mutex_unlock(&class->mutex);
 
 	return error;
 }
@@ -316,7 +316,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device)
  *
  * Note, you will need to drop the reference with put_device() after use.
  *
- * We hold class->sem in this function, so it can not be
+ * We hold class->mutex in this function, so it can not be
  * re-acquired in @match, otherwise it will self-deadlocking. For
  * example, calls to add or remove class members would be verboten.
  */
@@ -330,7 +330,7 @@ struct device *class_find_device(struct 
 	if (!class)
 		return NULL;
 
-	down(&class->sem);
+	mutex_lock(&class->mutex);
 	list_for_each_entry(dev, &class->devices, node) {
 		if (start) {
 			if (start == dev)
@@ -344,7 +344,7 @@ struct device *class_find_device(struct 
 		} else
 			put_device(dev);
 	}
-	up(&class->sem);
+	mutex_unlock(&class->mutex);
 
 	return found ? dev : NULL;
 }
@@ -362,13 +362,13 @@ int class_interface_register(struct clas
 	if (!parent)
 		return -EINVAL;
 
-	down(&parent->sem);
+	mutex_lock(&parent->mutex);
 	list_add_tail(&class_intf->node, &parent->interfaces);
 	if (class_intf->add_dev) {
 		list_for_each_entry(dev, &parent->devices, node)
 			class_intf->add_dev(dev, class_intf);
 	}
-	up(&parent->sem);
+	mutex_unlock(&parent->mutex);
 
 	return 0;
 }
@@ -381,13 +381,13 @@ void class_interface_unregister(struct c
 	if (!parent)
 		return;
 
-	down(&parent->sem);
+	mutex_lock(&parent->mutex);
 	list_del_init(&class_intf->node);
 	if (class_intf->remove_dev) {
 		list_for_each_entry(dev, &parent->devices, node)
 			class_intf->remove_dev(dev, class_intf);
 	}
-	up(&parent->sem);
+	mutex_unlock(&parent->mutex);
 
 	class_put(parent);
 }
diff -puN drivers/base/core.c~struct-class-sem-to-mutex-converting drivers/base/core.c
--- a/drivers/base/core.c~struct-class-sem-to-mutex-converting
+++ a/drivers/base/core.c
@@ -20,7 +20,6 @@
 #include <linux/notifier.h>
 #include <linux/genhd.h>
 #include <linux/kallsyms.h>
-#include <linux/semaphore.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -889,7 +888,7 @@ int device_add(struct device *dev)
 		klist_add_tail(&dev->knode_parent, &parent->klist_children);
 
 	if (dev->class) {
-		down(&dev->class->sem);
+		mutex_lock(&dev->class->mutex);
 		/* tie the class to the device */
 		list_add_tail(&dev->node, &dev->class->devices);
 
@@ -897,7 +896,7 @@ int device_add(struct device *dev)
 		list_for_each_entry(class_intf, &dev->class->interfaces, node)
 			if (class_intf->add_dev)
 				class_intf->add_dev(dev, class_intf);
-		up(&dev->class->sem);
+		mutex_unlock(&dev->class->mutex);
 	}
  Done:
 	put_device(dev);
@@ -998,14 +997,14 @@ void device_del(struct device *dev)
 	if (dev->class) {
 		device_remove_class_symlinks(dev);
 
-		down(&dev->class->sem);
+		mutex_lock(&dev->class->mutex);
 		/* notify any interfaces that the device is now gone */
 		list_for_each_entry(class_intf, &dev->class->interfaces, node)
 			if (class_intf->remove_dev)
 				class_intf->remove_dev(dev, class_intf);
 		/* remove the device from the class list */
 		list_del_init(&dev->node);
-		up(&dev->class->sem);
+		mutex_unlock(&dev->class->mutex);
 	}
 	device_remove_file(dev, &uevent_attr);
 	device_remove_attrs(dev);
diff -puN include/linux/device.h~struct-class-sem-to-mutex-converting include/linux/device.h
--- a/include/linux/device.h~struct-class-sem-to-mutex-converting
+++ a/include/linux/device.h
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/pm.h>
+#include <linux/mutex.h>
 #include <linux/semaphore.h>
 #include <asm/atomic.h>
 #include <asm/device.h>
@@ -185,7 +186,7 @@ struct class {
 	struct list_head	devices;
 	struct list_head	interfaces;
 	struct kset		class_dirs;
-	struct semaphore	sem; /* locks children, devices, interfaces */
+	struct mutex		mutex; /* locks devices, interfaces */
 	struct class_attribute		*class_attrs;
 	struct device_attribute		*dev_attrs;
 	struct kobject			*dev_kobj;
_


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][-mm] reclassify sg_sysfs_class for lockdep
  2008-05-28 14:40 ` James Bottomley
@ 2008-05-29  0:45   ` Dave Young
  2008-05-29  3:25     ` James Bottomley
  0 siblings, 1 reply; 6+ messages in thread
From: Dave Young @ 2008-05-29  0:45 UTC (permalink / raw)
  To: James Bottomley
  Cc: akpm, greg, matthew, kay.sievers, linux-kernel, linux-scsi

On Wed, May 28, 2008 at 10:40 PM, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
> On Tue, 2008-05-27 at 18:10 +0800, Dave Young wrote:
>> As register sg_interface, the sg_add will be called, which then will
>> add device to sg_sysfs_class. This will cause lockdep warning,
>> please see following email
>>
>> In this case the locks are from diffrent classi, one is sdev_class,
>> another is sg_sysfs_class
>>
>> Here reclassify the sg_sysfs_class for lockdep
>
> This isn't really a generic solution, is it?  It only works because we
> currently only have two users of the interface functions, so if we
> reclassify one they look separate to lockdep.  It will fall over again
> if we ever get another one.
>
> Surely the correct fix is to initialise lockdep for the mutex the same
> way we did for the semaphore in class_register() (which does exactly the
> same locking without triggering lockdep)?  That way we'll also fix the
> problem for other conversions of semaphore->mutex.

Matthew & greg did the work already.

>From my original idea I don't want to do this for all classes, and I
would think it as a rare case.

Regards
dave

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH][-mm] reclassify sg_sysfs_class for lockdep
  2008-05-29  0:45   ` Dave Young
@ 2008-05-29  3:25     ` James Bottomley
  0 siblings, 0 replies; 6+ messages in thread
From: James Bottomley @ 2008-05-29  3:25 UTC (permalink / raw)
  To: Dave Young; +Cc: akpm, greg, matthew, kay.sievers, linux-kernel, linux-scsi

On Thu, 2008-05-29 at 08:45 +0800, Dave Young wrote:
> > This isn't really a generic solution, is it?  It only works because we
> > currently only have two users of the interface functions, so if we
> > reclassify one they look separate to lockdep.  It will fall over again
> > if we ever get another one.
> >
> > Surely the correct fix is to initialise lockdep for the mutex the same
> > way we did for the semaphore in class_register() (which does exactly the
> > same locking without triggering lockdep)?  That way we'll also fix the
> > problem for other conversions of semaphore->mutex.
> 
> Matthew & greg did the work already.

Yes, that was nice of them ...

> >From my original idea I don't want to do this for all classes, and I
> would think it as a rare case.

Hardly ... the fact that it showed up in two different cases indicated
the problem to be more generic.

The root cause of the problem was that mutexes are part of the lockdep
infrastructure whereas semaphores aren't and the dynamic initialisation
of mutexes becomes a lockdep problem unless they're keyed and
initiallised correctly. If you want to do more semaphore->mutex
conversions, it would really be useful for you to understand what was
done and why it was necessary ... because it's going to become necessary
again in others of them.

James



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-05-29  3:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-27 10:10 [PATCH][-mm] reclassify sg_sysfs_class for lockdep Dave Young
2008-05-28 14:40 ` James Bottomley
2008-05-29  0:45   ` Dave Young
2008-05-29  3:25     ` James Bottomley
2008-05-28 14:49 ` Matthew Wilcox
2008-05-28 19:18   ` Andrew Morton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).