RDMA/hfi1: Convert from atomic_t to refcount_t on hfi1_devdata->user_refcount
authorXiyu Yang <xiyuyang19@fudan.edu.cn>
Mon, 19 Jul 2021 06:00:53 +0000 (14:00 +0800)
committerJason Gunthorpe <jgg@nvidia.com>
Fri, 30 Jul 2021 12:34:26 +0000 (09:34 -0300)
refcount_t type and corresponding API can protect refcounters from
accidental underflow and overflow and further use-after-free situations.

Link: https://lore.kernel.org/r/1626674454-56075-1-git-send-email-xiyuyang19@fudan.edu.cn
Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
Tested-by: Josh Fisher <josh.fisher@cornelisnetworks.com>
Acked-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/file_ops.c
drivers/infiniband/hw/hfi1/hfi.h
drivers/infiniband/hw/hfi1/init.c

index c9754463836741fc832fc0570c35d78ba5262971..50ffb824462550b225c292abb0a0bb57aa2c9b98 100644 (file)
@@ -15336,7 +15336,7 @@ int hfi1_init_dd(struct hfi1_devdata *dd)
        init_completion(&dd->user_comp);
 
        /* The user refcount starts with one to inidicate an active device */
-       atomic_set(&dd->user_refcount, 1);
+       refcount_set(&dd->user_refcount, 1);
 
        goto bail;
 
index 955c3637980e8e37849092d9c7a2520a17a6da5b..6dbfb794c255b6feb1f2ae23a09f394760058f44 100644 (file)
@@ -194,7 +194,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
        if (!((dd->flags & HFI1_PRESENT) && dd->kregbase1))
                return -EINVAL;
 
-       if (!atomic_inc_not_zero(&dd->user_refcount))
+       if (!refcount_inc_not_zero(&dd->user_refcount))
                return -ENXIO;
 
        /* The real work is performed later in assign_ctxt() */
@@ -213,7 +213,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
 nomem:
        kfree(fd);
        fp->private_data = NULL;
-       if (atomic_dec_and_test(&dd->user_refcount))
+       if (refcount_dec_and_test(&dd->user_refcount))
                complete(&dd->user_comp);
        return -ENOMEM;
 }
@@ -711,7 +711,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
        deallocate_ctxt(uctxt);
 done:
 
-       if (atomic_dec_and_test(&dd->user_refcount))
+       if (refcount_dec_and_test(&dd->user_refcount))
                complete(&dd->user_comp);
 
        cleanup_srcu_struct(&fdata->pq_srcu);
index 31664f43c27fefdf14c0d88f43557c2978a39b61..6cf03d16a495e6be966e958e6e6bf2b00baddc13 100644 (file)
@@ -48,6 +48,7 @@
  *
  */
 
+#include <linux/refcount.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -1384,7 +1385,7 @@ struct hfi1_devdata {
        /* Number of verbs contexts which have disabled ASPM */
        atomic_t aspm_disabled_cnt;
        /* Keeps track of user space clients */
-       atomic_t user_refcount;
+       refcount_t user_refcount;
        /* Used to wait for outstanding user space clients before dev removal */
        struct completion user_comp;
 
index 34106e5be679433b9181bec1a610901d6d1ff970..f37b157dbdb224043432ea15da00418c73f5dddf 100644 (file)
@@ -1747,7 +1747,7 @@ static void wait_for_clients(struct hfi1_devdata *dd)
         * Remove the device init value and complete the device if there is
         * no clients or wait for active clients to finish.
         */
-       if (atomic_dec_and_test(&dd->user_refcount))
+       if (refcount_dec_and_test(&dd->user_refcount))
                complete(&dd->user_comp);
 
        wait_for_completion(&dd->user_comp);