diff options
-rw-r--r-- | drivers/infiniband/core/user_mad.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 1fc17940a765..ef6dd825fee9 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/kref.h> | 47 | #include <linux/kref.h> |
48 | #include <linux/compat.h> | 48 | #include <linux/compat.h> |
49 | #include <linux/semaphore.h> | 49 | #include <linux/semaphore.h> |
50 | #include <linux/smp_lock.h> | ||
51 | 50 | ||
52 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
53 | 52 | ||
@@ -778,23 +777,33 @@ static long ib_umad_compat_ioctl(struct file *filp, unsigned int cmd, | |||
778 | } | 777 | } |
779 | #endif | 778 | #endif |
780 | 779 | ||
780 | /* | ||
781 | * ib_umad_open() does not need the BKL: | ||
782 | * | ||
783 | * - umad_port[] accesses are protected by port_lock, the | ||
784 | * ib_umad_port structures are properly reference counted, and | ||
785 | * everything else is purely local to the file being created, so | ||
786 | * races against other open calls are not a problem; | ||
787 | * - the ioctl method does not affect any global state outside of the | ||
788 | * file structure being operated on; | ||
789 | * - the port is added to umad_port[] as the last part of module | ||
790 | * initialization so the open method will either immediately run | ||
791 | * -ENXIO, or all required initialization will be done. | ||
792 | */ | ||
781 | static int ib_umad_open(struct inode *inode, struct file *filp) | 793 | static int ib_umad_open(struct inode *inode, struct file *filp) |
782 | { | 794 | { |
783 | struct ib_umad_port *port; | 795 | struct ib_umad_port *port; |
784 | struct ib_umad_file *file; | 796 | struct ib_umad_file *file; |
785 | int ret = 0; | 797 | int ret = 0; |
786 | 798 | ||
787 | lock_kernel(); | ||
788 | spin_lock(&port_lock); | 799 | spin_lock(&port_lock); |
789 | port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; | 800 | port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; |
790 | if (port) | 801 | if (port) |
791 | kref_get(&port->umad_dev->ref); | 802 | kref_get(&port->umad_dev->ref); |
792 | spin_unlock(&port_lock); | 803 | spin_unlock(&port_lock); |
793 | 804 | ||
794 | if (!port) { | 805 | if (!port) |
795 | unlock_kernel(); | ||
796 | return -ENXIO; | 806 | return -ENXIO; |
797 | } | ||
798 | 807 | ||
799 | mutex_lock(&port->file_mutex); | 808 | mutex_lock(&port->file_mutex); |
800 | 809 | ||
@@ -823,7 +832,6 @@ static int ib_umad_open(struct inode *inode, struct file *filp) | |||
823 | 832 | ||
824 | out: | 833 | out: |
825 | mutex_unlock(&port->file_mutex); | 834 | mutex_unlock(&port->file_mutex); |
826 | unlock_kernel(); | ||
827 | return ret; | 835 | return ret; |
828 | } | 836 | } |
829 | 837 | ||