]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
IB/iser: Prevent invalidating wrong MR
authorSergey Gorenko <sergeygo@nvidia.com>
Tue, 19 Dec 2023 07:23:11 +0000 (09:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Jan 2024 22:52:45 +0000 (14:52 -0800)
[ Upstream commit 2f1888281e67205bd80d3e8f54dbd519a9653f26 ]

The iser_reg_resources structure has two pointers to MR but only one
mr_valid field. The implementation assumes that we use only *sig_mr when
pi_enable is true. Otherwise, we use only *mr. However, it is only
sometimes correct. Read commands without protection information occur even
when pi_enble is true. For example, the following SCSI commands have a
Data-In buffer but never have protection information: READ CAPACITY (16),
INQUIRY, MODE SENSE(6), MAINTENANCE IN. So, we use
*sig_mr for some SCSI commands and *mr for the other SCSI commands.

In most cases, it works fine because the remote invalidation is applied.
However, there are two cases when the remote invalidation is not
applicable.
 1. Small write commands when all data is sent as an immediate.
 2. The target does not support the remote invalidation feature.

The lazy invalidation is used if the remote invalidation is impossible.
Since, at the lazy invalidation, we always invalidate the MR we want to
use, the wrong MR may be invalidated.

To fix the issue, we need a field per MR that indicates the MR needs
invalidation. Since the ib_mr structure already has such a field, let's
use ib_mr.need_inval instead of iser_reg_resources.mr_valid.

Fixes: b76a439982f8 ("IB/iser: Use IB_WR_REG_MR_INTEGRITY for PI handover")
Link: https://lore.kernel.org/r/20231219072311.40989-1-sergeygo@nvidia.com
Acked-by: Max Gurtovoy <mgurtovoy@nvidia.com>
Signed-off-by: Sergey Gorenko <sergeygo@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/infiniband/ulp/iser/iser_initiator.c
drivers/infiniband/ulp/iser/iser_memory.c
drivers/infiniband/ulp/iser/iser_verbs.c

index 9f6ac0a09a78245c270b73319523ff1d66e38993..35cc0a57e69751733d9bc7af3edb7f65e291e49a 100644 (file)
@@ -321,12 +321,10 @@ struct iser_device {
  *
  * @mr:         memory region
  * @sig_mr:     signature memory region
- * @mr_valid:   is mr valid indicator
  */
 struct iser_reg_resources {
        struct ib_mr                     *mr;
        struct ib_mr                     *sig_mr;
-       u8                                mr_valid:1;
 };
 
 /**
index 27a6f75a9912ff2d005bbfc01719bc6646994f89..9ea88dd6a414e20e59458b3a7377950500f2902b 100644 (file)
@@ -602,7 +602,10 @@ iser_inv_desc(struct iser_fr_desc *desc, u32 rkey)
                return -EINVAL;
        }
 
-       desc->rsc.mr_valid = 0;
+       if (desc->sig_protected)
+               desc->rsc.sig_mr->need_inval = false;
+       else
+               desc->rsc.mr->need_inval = false;
 
        return 0;
 }
index 9776b755d84872ce8a6c119cf83cf67ad479320b..c362043e7f1726755fd425bf049981076667f6c3 100644 (file)
@@ -250,7 +250,7 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task,
 
        iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask);
 
-       if (rsc->mr_valid)
+       if (rsc->sig_mr->need_inval)
                iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr);
 
        ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey));
@@ -274,7 +274,7 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task,
        wr->access = IB_ACCESS_LOCAL_WRITE |
                     IB_ACCESS_REMOTE_READ |
                     IB_ACCESS_REMOTE_WRITE;
-       rsc->mr_valid = 1;
+       rsc->sig_mr->need_inval = true;
 
        sig_reg->sge.lkey = mr->lkey;
        sig_reg->rkey = mr->rkey;
@@ -299,7 +299,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
        struct ib_reg_wr *wr = &tx_desc->reg_wr;
        int n;
 
-       if (rsc->mr_valid)
+       if (rsc->mr->need_inval)
                iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr);
 
        ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey));
@@ -322,7 +322,7 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
                     IB_ACCESS_REMOTE_WRITE |
                     IB_ACCESS_REMOTE_READ;
 
-       rsc->mr_valid = 1;
+       rsc->mr->need_inval = true;
 
        reg->sge.lkey = mr->lkey;
        reg->rkey = mr->rkey;
index b566f7cb7797b819c6b3b3d4254ef4426ce63144..8656664a15c5f4cbefeb0cf59bc1a63305aa849e 100644 (file)
@@ -136,7 +136,6 @@ iser_create_fastreg_desc(struct iser_device *device,
                        goto err_alloc_mr_integrity;
                }
        }
-       desc->rsc.mr_valid = 0;
 
        return desc;