diff options
author | Jonathan Corbet <corbet@lwn.net> | 2008-08-26 19:15:45 -0400 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2008-10-16 14:32:26 -0400 |
commit | 0d4a7bc12ffecd3ba41dd94179cc5b272b71ce8a (patch) | |
tree | 40fb095468564e1bcd64ee9a01ac409406cc36d3 | |
parent | 3fa8749e584b55f1180411ab1b51117190bac1e5 (diff) |
UIO: BKL removal
Fill in needed locking around idr accesses, then remove the big kernel lock
from the UIO driver. Since there are no in-tree UIO drivers with open()
methods, no further BKL pushdown is required.
Acked-by: Hans J. Koch <hjk@linutronix.de>
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
-rw-r--r-- | drivers/uio/uio.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 3a6934bf7131..4f28f4bf8366 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -47,6 +47,9 @@ static struct uio_class { | |||
47 | struct class *class; | 47 | struct class *class; |
48 | } *uio_class; | 48 | } *uio_class; |
49 | 49 | ||
50 | /* Protect idr accesses */ | ||
51 | static DEFINE_MUTEX(minor_lock); | ||
52 | |||
50 | /* | 53 | /* |
51 | * attributes | 54 | * attributes |
52 | */ | 55 | */ |
@@ -231,7 +234,6 @@ static void uio_dev_del_attributes(struct uio_device *idev) | |||
231 | 234 | ||
232 | static int uio_get_minor(struct uio_device *idev) | 235 | static int uio_get_minor(struct uio_device *idev) |
233 | { | 236 | { |
234 | static DEFINE_MUTEX(minor_lock); | ||
235 | int retval = -ENOMEM; | 237 | int retval = -ENOMEM; |
236 | int id; | 238 | int id; |
237 | 239 | ||
@@ -253,7 +255,9 @@ exit: | |||
253 | 255 | ||
254 | static void uio_free_minor(struct uio_device *idev) | 256 | static void uio_free_minor(struct uio_device *idev) |
255 | { | 257 | { |
258 | mutex_lock(&minor_lock); | ||
256 | idr_remove(&uio_idr, idev->minor); | 259 | idr_remove(&uio_idr, idev->minor); |
260 | mutex_unlock(&minor_lock); | ||
257 | } | 261 | } |
258 | 262 | ||
259 | /** | 263 | /** |
@@ -297,8 +301,9 @@ static int uio_open(struct inode *inode, struct file *filep) | |||
297 | struct uio_listener *listener; | 301 | struct uio_listener *listener; |
298 | int ret = 0; | 302 | int ret = 0; |
299 | 303 | ||
300 | lock_kernel(); | 304 | mutex_lock(&minor_lock); |
301 | idev = idr_find(&uio_idr, iminor(inode)); | 305 | idev = idr_find(&uio_idr, iminor(inode)); |
306 | mutex_unlock(&minor_lock); | ||
302 | if (!idev) { | 307 | if (!idev) { |
303 | ret = -ENODEV; | 308 | ret = -ENODEV; |
304 | goto out; | 309 | goto out; |
@@ -324,18 +329,15 @@ static int uio_open(struct inode *inode, struct file *filep) | |||
324 | if (ret) | 329 | if (ret) |
325 | goto err_infoopen; | 330 | goto err_infoopen; |
326 | } | 331 | } |
327 | unlock_kernel(); | ||
328 | return 0; | 332 | return 0; |
329 | 333 | ||
330 | err_infoopen: | 334 | err_infoopen: |
331 | |||
332 | kfree(listener); | 335 | kfree(listener); |
333 | err_alloc_listener: | ||
334 | 336 | ||
337 | err_alloc_listener: | ||
335 | module_put(idev->owner); | 338 | module_put(idev->owner); |
336 | 339 | ||
337 | out: | 340 | out: |
338 | unlock_kernel(); | ||
339 | return ret; | 341 | return ret; |
340 | } | 342 | } |
341 | 343 | ||