aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/sysfs.h
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2012-05-14 13:30:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-14 15:19:56 -0400
commit356c05d58af05d582e634b54b40050c73609617b (patch)
tree49fd49203678cee0e7650f1b4d55aa3f53527575 /include/linux/sysfs.h
parentc836d0ab70acf7b7bd2b698278e8abae9e6d9978 (diff)
sysfs: get rid of some lockdep false positives
This patch (as1554) fixes a lockdep false-positive report. The problem arises because lockdep is unable to deal with the tree-structured locks created by the device core and sysfs. This particular problem involves a sysfs attribute method that unregisters itself, not from the device it was called for, but from a descendant device. Lockdep doesn't understand the distinction and reports a possible deadlock, even though the operation is safe. This is the sort of thing that would normally be handled by using a nested lock annotation; unfortunately it's not feasible to do that here. There's no sensible way to tell sysfs when attribute removal occurs in the context of a parent attribute method. As a workaround, the patch adds a new flag to struct attribute telling sysfs not to inform lockdep when it acquires a readlock on a sysfs_dirent instance for the attribute. The readlock is still acquired, but lockdep doesn't know about it and hence does not complain about impossible deadlock scenarios. Also added are macros for static initialization of attribute structures with the ignore_lockdep flag set. The three offending attributes in the USB subsystem are converted to use the new macros. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Tejun Heo <tj@kernel.org> CC: Eric W. Biederman <ebiederm@xmission.com> CC: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/sysfs.h')
-rw-r--r--include/linux/sysfs.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 0010009b2f00..381f06db2fe5 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -27,6 +27,7 @@ struct attribute {
27 const char *name; 27 const char *name;
28 umode_t mode; 28 umode_t mode;
29#ifdef CONFIG_DEBUG_LOCK_ALLOC 29#ifdef CONFIG_DEBUG_LOCK_ALLOC
30 bool ignore_lockdep:1;
30 struct lock_class_key *key; 31 struct lock_class_key *key;
31 struct lock_class_key skey; 32 struct lock_class_key skey;
32#endif 33#endif
@@ -80,6 +81,17 @@ struct attribute_group {
80 81
81#define __ATTR_NULL { .attr = { .name = NULL } } 82#define __ATTR_NULL { .attr = { .name = NULL } }
82 83
84#ifdef CONFIG_DEBUG_LOCK_ALLOC
85#define __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) { \
86 .attr = {.name = __stringify(_name), .mode = _mode, \
87 .ignore_lockdep = true }, \
88 .show = _show, \
89 .store = _store, \
90}
91#else
92#define __ATTR_IGNORE_LOCKDEP __ATTR
93#endif
94
83#define attr_name(_attr) (_attr).attr.name 95#define attr_name(_attr) (_attr).attr.name
84 96
85struct file; 97struct file;