All of lore.kernel.org
 help / color / mirror / Atom feed
From: "yanjun.zhu" <yanjun.zhu@linux.dev>
To: Jason Gunthorpe <jgg@nvidia.com>,
	Junxian Huang <huangjunxian6@hisilicon.com>,
	Krzysztof Czurylo <krzysztof.czurylo@intel.com>,
	linux-rdma@vger.kernel.org,
	Chengchang Tang <tangchengchang@huawei.com>,
	Tatyana Nikolova <tatyana.e.nikolova@intel.com>,
	Yishai Hadas <yishaih@nvidia.com>,
	Zhu Yanjun <zyjzyj2000@gmail.com>,
	Zhu Yanjun <yanjun.zhu@linux.dev>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	David Hildenbrand <david@redhat.com>,
	Leon Romanovsky <leon@kernel.org>,
	patches@lists.linux.dev,
	Philip Tsukerman <philiptsukerman@gmail.com>,
	stable@vger.kernel.org
Subject: Re: [PATCH] RDMA: During rereg_mr ensure that REREG_ACCESS is compatible
Date: Mon, 8 Jun 2026 15:38:32 -0700	[thread overview]
Message-ID: <22629c63-ca98-4af7-9e3b-480b89be6ce1@linux.dev> (raw)
In-Reply-To: <0-v1-06fb1a2d6cf5+107-rereg_access_jgg@nvidia.com>

On 6/8/26 9:44 AM, Jason Gunthorpe wrote:
> If IB_MR_REREG_ACCESS changes from RO to RW then the umem has to be
> re-evaluated to ensure it is properly pinned as RW. Since the umem is
> hidden inside each driver's mr struct add a ib_umem_check_rereg() function
> that each driver has to call before processing IB_MR_REREG_ACCESS.
> 
> mlx4 has to retain its duplicate ib_access_writable check because it
> implements IB_MR_REREG_ACCESS | IB_MR_REREG_TRANS by changing both items
> in place sequentially while the MR is live, so it will continue to not
> support this combination.
> 
> Cc: stable@vger.kernel.org
> Fixes: b40656aa7d55 ("RDMA/umem: remove FOLL_FORCE usage")
> Reported-by: Philip Tsukerman <philiptsukerman@gmail.com>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
> ---
>   drivers/infiniband/core/umem.c          | 16 ++++++++++++++++
>   drivers/infiniband/hw/hns/hns_roce_mr.c |  4 ++++
>   drivers/infiniband/hw/irdma/verbs.c     |  4 ++++
>   drivers/infiniband/hw/mlx4/mr.c         |  4 ++++
>   drivers/infiniband/hw/mlx5/mr.c         |  4 ++++
>   drivers/infiniband/sw/rxe/rxe_verbs.c   |  5 +++++
>   include/rdma/ib_umem.h                  |  8 ++++++++
>   7 files changed, 45 insertions(+)
> 
> diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
> index 786fa1aa8e552b..4b055712b0d0db 100644
> --- a/drivers/infiniband/core/umem.c
> +++ b/drivers/infiniband/core/umem.c
> @@ -332,3 +332,19 @@ int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
>   		return 0;
>   }
>   EXPORT_SYMBOL(ib_umem_copy_from);
> +
> +/*
> + * Called during rereg mr if the driver is able to re-use a umem for
> + * IB_MR_REREG_ACCESS.
> + */
> +int ib_umem_check_rereg(struct ib_umem *umem, int flags, int new_access_flags)
> +{
> +	if (!umem)
> +		return 0;
> +
> +	if ((flags & IB_MR_REREG_ACCESS) && !(flags & IB_MR_REREG_TRANS))
> +		if (ib_access_writable(new_access_flags) && !umem->writable)
> +			return -EACCES;
> +	return 0;
> +}
> +EXPORT_SYMBOL(ib_umem_check_rereg);
> diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
> index 896af1828a38de..25bfd3970f5b6e 100644
> --- a/drivers/infiniband/hw/hns/hns_roce_mr.c
> +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
> @@ -300,6 +300,10 @@ struct ib_mr *hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start,
>   		goto err_out;
>   	}
>   
> +	ret = ib_umem_check_rereg(mr->pbl_mtr.umem, flags, mr_access_flags);
> +	if (ret)
> +		goto err_out;
> +
>   	mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
>   	ret = PTR_ERR_OR_ZERO(mailbox);
>   	if (ret)
> diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
> index 17086048d2d7fc..8cd4275328052e 100644
> --- a/drivers/infiniband/hw/irdma/verbs.c
> +++ b/drivers/infiniband/hw/irdma/verbs.c
> @@ -3803,6 +3803,10 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags,
>   	if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS))
>   		return ERR_PTR(-EOPNOTSUPP);
>   
> +	ret = ib_umem_check_rereg(iwmr->region, flags, new_access);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
>   	if (dmabuf_revocable) {
>   		umem_dmabuf = to_ib_umem_dmabuf(iwmr->region);
>   
> diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
> index 650b4a9121ff6d..6747bca3067770 100644
> --- a/drivers/infiniband/hw/mlx4/mr.c
> +++ b/drivers/infiniband/hw/mlx4/mr.c
> @@ -209,6 +209,10 @@ struct ib_mr *mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags, u64 start,
>   	struct mlx4_mpt_entry **pmpt_entry = &mpt_entry;
>   	int err;
>   
> +	err = ib_umem_check_rereg(mmr->umem, flags, mr_access_flags);
> +	if (err)
> +		return ERR_PTR(err);
> +
>   	/* Since we synchronize this call and mlx4_ib_dereg_mr via uverbs,
>   	 * we assume that the calls can't run concurrently. Otherwise, a
>   	 * race exists.
> diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
> index 3b6da45061a552..fb40b44496f47a 100644
> --- a/drivers/infiniband/hw/mlx5/mr.c
> +++ b/drivers/infiniband/hw/mlx5/mr.c
> @@ -1179,6 +1179,10 @@ struct ib_mr *mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
>   	if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS))
>   		return ERR_PTR(-EOPNOTSUPP);
>   
> +	err = ib_umem_check_rereg(mr->umem, flags, new_access_flags);
> +	if (err)
> +		return ERR_PTR(err);
> +
>   	if (!(flags & IB_MR_REREG_ACCESS))
>   		new_access_flags = mr->access_flags;
>   	if (!(flags & IB_MR_REREG_PD))
> diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
> index 4d4891dc28846b..4cf04a44189c64 100644
> --- a/drivers/infiniband/sw/rxe/rxe_verbs.c
> +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
> @@ -1319,6 +1319,7 @@ static struct ib_mr *rxe_rereg_user_mr(struct ib_mr *ibmr, int flags,
>   	struct rxe_mr *mr = to_rmr(ibmr);
>   	struct rxe_pd *old_pd = to_rpd(ibmr->pd);
>   	struct rxe_pd *pd = to_rpd(ibpd);
> +	int err;
>   
>   	/* for now only support the two easy cases:
>   	 * rereg_pd and rereg_access
> @@ -1328,6 +1329,10 @@ static struct ib_mr *rxe_rereg_user_mr(struct ib_mr *ibmr, int flags,
>   		return ERR_PTR(-EOPNOTSUPP);
>   	}
>   
> +	err = ib_umem_check_rereg(mr->umem, flags, access);
> +	if (err)
> +		return ERR_PTR(err);
> +

Thanks a lot. I am fine with this.

Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>

But I found the following problem. I am not sure if we fix this problem 
in this commit or file a new commit.

diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c 
b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 4d4891dc2884..3b99649c342d 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -1319,6 +1319,7 @@ static struct ib_mr *rxe_rereg_user_mr(struct 
ib_mr *ibmr, int flags,
         struct rxe_mr *mr = to_rmr(ibmr);
         struct rxe_pd *old_pd = to_rpd(ibmr->pd);
         struct rxe_pd *pd = to_rpd(ibpd);
+       struct ib_pd *old_ibpd;

         /* for now only support the two easy cases:
          * rereg_pd and rereg_access
@@ -1331,12 +1332,18 @@ static struct ib_mr *rxe_rereg_user_mr(struct 
ib_mr *ibmr, int flags,
         if (flags & IB_MR_REREG_PD) {
                 rxe_put(old_pd);
                 rxe_get(pd);
+               old_ibpd = mr->ibmr.pd;
                 mr->ibmr.pd = ibpd;
         }

         if (flags & IB_MR_REREG_ACCESS) {
                 if (access & ~RXE_ACCESS_SUPPORTED_MR) {
                         rxe_err_mr(mr, "access = %#x not supported\n", 
access);
+                       if (flags & IB_MR_REREG_PD) {
+                               rxe_get(old_pd);
+                               rxe_put(pd);
+                               mr->ibmr.pd = old_ibpd;
+                       }
                         return ERR_PTR(-EOPNOTSUPP);
                 }
                 mr->access = access;

Zhu Yanjun

>   	if (flags & IB_MR_REREG_PD) {
>   		rxe_put(old_pd);
>   		rxe_get(pd);
> diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
> index 2ad52cc1d52bdd..49172098a8de14 100644
> --- a/include/rdma/ib_umem.h
> +++ b/include/rdma/ib_umem.h
> @@ -156,6 +156,8 @@ void ib_umem_dmabuf_revoke_lock(struct ib_umem_dmabuf *umem_dmabuf);
>   void ib_umem_dmabuf_revoke_unlock(struct ib_umem_dmabuf *umem_dmabuf);
>   void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf);
>   
> +int ib_umem_check_rereg(struct ib_umem *umem, int flags, int new_access_flags);
> +
>   #else /* CONFIG_INFINIBAND_USER_MEM */
>   
>   #include <linux/err.h>
> @@ -230,5 +232,11 @@ static inline void ib_umem_dmabuf_revoke_lock(struct ib_umem_dmabuf *umem_dmabuf
>   static inline void ib_umem_dmabuf_revoke_unlock(struct ib_umem_dmabuf *umem_dmabuf) {}
>   static inline void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf) {}
>   
> +static inline int ib_umem_check_rereg(struct ib_umem *umem, int flags,
> +				      int new_access_flags)
> +{
> +	return -EOPNOTSUPP;
> +}
> +
>   #endif /* CONFIG_INFINIBAND_USER_MEM */
>   #endif /* IB_UMEM_H */
> 
> base-commit: 323c98a4ff06aa28114f2bf658fb43eb3b536bbc


  reply	other threads:[~2026-06-08 22:39 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-08 16:44 [PATCH] RDMA: During rereg_mr ensure that REREG_ACCESS is compatible Jason Gunthorpe
2026-06-08 22:38 ` yanjun.zhu [this message]
2026-06-08 23:25   ` Jason Gunthorpe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=22629c63-ca98-4af7-9e3b-480b89be6ce1@linux.dev \
    --to=yanjun.zhu@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=david@redhat.com \
    --cc=huangjunxian6@hisilicon.com \
    --cc=jgg@nvidia.com \
    --cc=krzysztof.czurylo@intel.com \
    --cc=leon@kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=philiptsukerman@gmail.com \
    --cc=stable@vger.kernel.org \
    --cc=tangchengchang@huawei.com \
    --cc=tatyana.e.nikolova@intel.com \
    --cc=yishaih@nvidia.com \
    --cc=zyjzyj2000@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.