IB/hfi1: Reserve user expected TIDs
authorDean Luick <dean.luick@cornelisnetworks.com>
Mon, 9 Jan 2023 17:31:16 +0000 (12:31 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 1 Feb 2023 07:27:05 +0000 (08:27 +0100)
[ Upstream commit ecf91551cdd2925ed6d9a9d99074fa5f67b90596 ]

To avoid a race, reserve the number of user expected
TIDs before setup.

Fixes: 7e7a436ecb6e ("staging/hfi1: Add TID entry program function body")
Signed-off-by: Dean Luick <dean.luick@cornelisnetworks.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
Link: https://lore.kernel.org/r/167328547636.1472310.7419712824785353905.stgit@awfm-02.cornelisnetworks.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/infiniband/hw/hfi1/user_exp_rcv.c

index 212273f..236cfc5 100644 (file)
@@ -282,16 +282,13 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
        /* Find sets of physically contiguous pages */
        tidbuf->n_psets = find_phys_blocks(tidbuf, pinned);
 
-       /*
-        * We don't need to access this under a lock since tid_used is per
-        * process and the same process cannot be in hfi1_user_exp_rcv_clear()
-        * and hfi1_user_exp_rcv_setup() at the same time.
-        */
+       /* Reserve the number of expected tids to be used. */
        spin_lock(&fd->tid_lock);
        if (fd->tid_used + tidbuf->n_psets > fd->tid_limit)
                pageset_count = fd->tid_limit - fd->tid_used;
        else
                pageset_count = tidbuf->n_psets;
+       fd->tid_used += pageset_count;
        spin_unlock(&fd->tid_lock);
 
        if (!pageset_count)
@@ -400,10 +397,11 @@ unlock:
 nomem:
        hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx,
                  mapped_pages, ret);
+       /* adjust reserved tid_used to actual count */
+       spin_lock(&fd->tid_lock);
+       fd->tid_used -= pageset_count - tididx;
+       spin_unlock(&fd->tid_lock);
        if (tididx) {
-               spin_lock(&fd->tid_lock);
-               fd->tid_used += tididx;
-               spin_unlock(&fd->tid_lock);
                tinfo->tidcnt = tididx;
                tinfo->length = mapped_pages * PAGE_SIZE;