diff options
| -rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 8ede1e475ce6..fdfcf7910d9a 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
| @@ -45,7 +45,6 @@ | |||
| 45 | #include <linux/file.h> | 45 | #include <linux/file.h> |
| 46 | #include <linux/mount.h> | 46 | #include <linux/mount.h> |
| 47 | #include <linux/cdev.h> | 47 | #include <linux/cdev.h> |
| 48 | #include <linux/smp_lock.h> | ||
| 49 | 48 | ||
| 50 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
| 51 | 50 | ||
| @@ -611,23 +610,32 @@ static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma) | |||
| 611 | return file->device->ib_dev->mmap(file->ucontext, vma); | 610 | return file->device->ib_dev->mmap(file->ucontext, vma); |
| 612 | } | 611 | } |
| 613 | 612 | ||
| 613 | /* | ||
| 614 | * ib_uverbs_open() does not need the BKL: | ||
| 615 | * | ||
| 616 | * - dev_table[] accesses are protected by map_lock, the | ||
| 617 | * ib_uverbs_device structures are properly reference counted, and | ||
| 618 | * everything else is purely local to the file being created, so | ||
| 619 | * races against other open calls are not a problem; | ||
| 620 | * - there is no ioctl method to race against; | ||
| 621 | * - the device is added to dev_table[] as the last part of module | ||
| 622 | * initialization, the open method will either immediately run | ||
| 623 | * -ENXIO, or all required initialization will be done. | ||
| 624 | */ | ||
| 614 | static int ib_uverbs_open(struct inode *inode, struct file *filp) | 625 | static int ib_uverbs_open(struct inode *inode, struct file *filp) |
| 615 | { | 626 | { |
| 616 | struct ib_uverbs_device *dev; | 627 | struct ib_uverbs_device *dev; |
| 617 | struct ib_uverbs_file *file; | 628 | struct ib_uverbs_file *file; |
| 618 | int ret; | 629 | int ret; |
| 619 | 630 | ||
| 620 | lock_kernel(); | ||
| 621 | spin_lock(&map_lock); | 631 | spin_lock(&map_lock); |
| 622 | dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR]; | 632 | dev = dev_table[iminor(inode) - IB_UVERBS_BASE_MINOR]; |
| 623 | if (dev) | 633 | if (dev) |
| 624 | kref_get(&dev->ref); | 634 | kref_get(&dev->ref); |
| 625 | spin_unlock(&map_lock); | 635 | spin_unlock(&map_lock); |
| 626 | 636 | ||
| 627 | if (!dev) { | 637 | if (!dev) |
| 628 | unlock_kernel(); | ||
| 629 | return -ENXIO; | 638 | return -ENXIO; |
| 630 | } | ||
| 631 | 639 | ||
| 632 | if (!try_module_get(dev->ib_dev->owner)) { | 640 | if (!try_module_get(dev->ib_dev->owner)) { |
| 633 | ret = -ENODEV; | 641 | ret = -ENODEV; |
| @@ -648,7 +656,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) | |||
| 648 | 656 | ||
| 649 | filp->private_data = file; | 657 | filp->private_data = file; |
| 650 | 658 | ||
| 651 | unlock_kernel(); | ||
| 652 | return 0; | 659 | return 0; |
| 653 | 660 | ||
| 654 | err_module: | 661 | err_module: |
| @@ -656,7 +663,6 @@ err_module: | |||
| 656 | 663 | ||
| 657 | err: | 664 | err: |
| 658 | kref_put(&dev->ref, ib_uverbs_release_dev); | 665 | kref_put(&dev->ref, ib_uverbs_release_dev); |
| 659 | unlock_kernel(); | ||
| 660 | return ret; | 666 | return ret; |
| 661 | } | 667 | } |
| 662 | 668 | ||
