IB/uverbs: Do not block disassociate during write()
authorJason Gunthorpe <jgg@mellanox.com>
Thu, 26 Jul 2018 03:40:19 +0000 (21:40 -0600)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 1 Aug 2018 20:55:48 +0000 (14:55 -0600)
Now that all the callbacks are safe to run concurrently with
disassociation this test can be eliminated. The ufile core infrastructure
becomes entirely self contained and is not sensitive to disassociation.

Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/uverbs.h
drivers/infiniband/core/uverbs_main.c

index 5e21cc1f900b9a12c4f953750c03360e1e62cfda..0fa32009908c3d4d7647d5035bb2699ddf7f3a3d 100644 (file)
@@ -158,6 +158,9 @@ struct ib_uverbs_file {
        spinlock_t              uobjects_lock;
        struct list_head        uobjects;
 
+       u64 uverbs_cmd_mask;
+       u64 uverbs_ex_cmd_mask;
+
        struct idr              idr;
        /* spinlock protects write access to idr */
        spinlock_t              idr_lock;
index a1e427b2c2a1396945677c4a52bc1bbc25920e9b..a3213245aab2468e25e164eb68daafaf1b27af16 100644 (file)
@@ -646,13 +646,13 @@ err_put_refs:
        return filp;
 }
 
-static bool verify_command_mask(struct ib_device *ib_dev,
-                               u32 command, bool extended)
+static bool verify_command_mask(struct ib_uverbs_file *ufile, u32 command,
+                               bool extended)
 {
        if (!extended)
-               return ib_dev->uverbs_cmd_mask & BIT_ULL(command);
+               return ufile->uverbs_cmd_mask & BIT_ULL(command);
 
-       return ib_dev->uverbs_ex_cmd_mask & BIT_ULL(command);
+       return ufile->uverbs_ex_cmd_mask & BIT_ULL(command);
 }
 
 static bool verify_command_idx(u32 command, bool extended)
@@ -722,7 +722,6 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
 {
        struct ib_uverbs_file *file = filp->private_data;
        struct ib_uverbs_ex_cmd_hdr ex_hdr;
-       struct ib_device *ib_dev;
        struct ib_uverbs_cmd_hdr hdr;
        bool extended;
        int srcu_key;
@@ -757,14 +756,8 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                return ret;
 
        srcu_key = srcu_read_lock(&file->device->disassociate_srcu);
-       ib_dev = srcu_dereference(file->device->ib_dev,
-                                 &file->device->disassociate_srcu);
-       if (!ib_dev) {
-               ret = -EIO;
-               goto out;
-       }
 
-       if (!verify_command_mask(ib_dev, command, extended)) {
+       if (!verify_command_mask(file, command, extended)) {
                ret = -EOPNOTSUPP;
                goto out;
        }
@@ -889,6 +882,9 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
        mutex_unlock(&dev->lists_mutex);
        srcu_read_unlock(&dev->disassociate_srcu, srcu_key);
 
+       file->uverbs_cmd_mask = ib_dev->uverbs_cmd_mask;
+       file->uverbs_ex_cmd_mask = ib_dev->uverbs_ex_cmd_mask;
+
        return nonseekable_open(inode, filp);
 
 err_module: