diff options
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r-- | fs/sysfs/dir.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 24fa995f0312..e6bb9b2a4cbe 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -132,6 +132,24 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd) | |||
132 | rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children); | 132 | rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children); |
133 | } | 133 | } |
134 | 134 | ||
135 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
136 | |||
137 | /* Test for attributes that want to ignore lockdep for read-locking */ | ||
138 | static bool ignore_lockdep(struct sysfs_dirent *sd) | ||
139 | { | ||
140 | return sysfs_type(sd) == SYSFS_KOBJ_ATTR && | ||
141 | sd->s_attr.attr->ignore_lockdep; | ||
142 | } | ||
143 | |||
144 | #else | ||
145 | |||
146 | static inline bool ignore_lockdep(struct sysfs_dirent *sd) | ||
147 | { | ||
148 | return true; | ||
149 | } | ||
150 | |||
151 | #endif | ||
152 | |||
135 | /** | 153 | /** |
136 | * sysfs_get_active - get an active reference to sysfs_dirent | 154 | * sysfs_get_active - get an active reference to sysfs_dirent |
137 | * @sd: sysfs_dirent to get an active reference to | 155 | * @sd: sysfs_dirent to get an active reference to |
@@ -155,15 +173,17 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) | |||
155 | return NULL; | 173 | return NULL; |
156 | 174 | ||
157 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); | 175 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); |
158 | if (likely(t == v)) { | 176 | if (likely(t == v)) |
159 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); | 177 | break; |
160 | return sd; | ||
161 | } | ||
162 | if (t < 0) | 178 | if (t < 0) |
163 | return NULL; | 179 | return NULL; |
164 | 180 | ||
165 | cpu_relax(); | 181 | cpu_relax(); |
166 | } | 182 | } |
183 | |||
184 | if (likely(!ignore_lockdep(sd))) | ||
185 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); | ||
186 | return sd; | ||
167 | } | 187 | } |
168 | 188 | ||
169 | /** | 189 | /** |
@@ -180,7 +200,8 @@ void sysfs_put_active(struct sysfs_dirent *sd) | |||
180 | if (unlikely(!sd)) | 200 | if (unlikely(!sd)) |
181 | return; | 201 | return; |
182 | 202 | ||
183 | rwsem_release(&sd->dep_map, 1, _RET_IP_); | 203 | if (likely(!ignore_lockdep(sd))) |
204 | rwsem_release(&sd->dep_map, 1, _RET_IP_); | ||
184 | v = atomic_dec_return(&sd->s_active); | 205 | v = atomic_dec_return(&sd->s_active); |
185 | if (likely(v != SD_DEACTIVATED_BIAS)) | 206 | if (likely(v != SD_DEACTIVATED_BIAS)) |
186 | return; | 207 | return; |