FAILED: patch "[PATCH] RDMA: During rereg_mr ensure that REREG_ACCESS is compatible" failed to apply to 7.0-stable tree
Subsystems (7)
[email protected]
maintainerThe patch below does not apply to the 7.0-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.0.y
git checkout FETCH_HEAD
git cherry-pick -x badad6fad60def1b9805559dd81dbab3d97b82aa
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026061548-onshore-amendment-9a93@gregkh' --subject-prefix 'PATCH 7.0.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From badad6fad60def1b9805559dd81dbab3d97b82aa Mon Sep 17 00:00:00 2001
From: Jason Gunthorpe <[email protected]>
Date: Thu, 4 Jun 2026 15:03:13 -0300
Subject: [PATCH] RDMA: During rereg_mr ensure that REREG_ACCESS is compatible
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.
drivers/infiniband/core/umem.c +16 -0
@@ -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);
drivers/infiniband/hw/hns/hns_roce_mr.c +4 -0
@@ -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)
drivers/infiniband/hw/irdma/verbs.c +4 -0
@@ -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);
drivers/infiniband/hw/mlx4/mr.c +4 -0
@@ -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.
drivers/infiniband/hw/mlx5/mr.c +4 -0
@@ -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 ))
drivers/infiniband/sw/rxe/rxe_verbs.c +5 -0
@@ -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); +if (flags &IB_MR_REREG_PD ) {rxe_put (old_pd);rxe_get (pd);
include/rdma/ib_umem.h +8 -0
@@ -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_dmabufstatic 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 */
Jason Gunthorpe
maintainerPATCH 1/1 RDMA: During rereg_mr ensure that REREG_ACCESS is compatible
commit badad6fad60def1b9805559dd81dbab3d97b82aa upstream.
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.
--- 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(+)
drivers/infiniband/core/umem.c +16 -0
@@ -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);
drivers/infiniband/hw/hns/hns_roce_mr.c +4 -0
@@ -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)
drivers/infiniband/hw/irdma/verbs.c +4 -0
@@ -3759,6 +3759,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); + ret =irdma_hwdereg_mr (ib_mr);if (ret)return ERR_PTR (ret);
drivers/infiniband/hw/mlx4/mr.c +4 -0
@@ -208,6 +208,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.
drivers/infiniband/hw/mlx5/mr.c +4 -0
@@ -1895,6 +1895,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 ))
drivers/infiniband/sw/rxe/rxe_verbs.c +5 -0
@@ -1332,6 +1332,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
@@ -1341,6 +1342,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); +if (flags &IB_MR_REREG_PD ) {rxe_put (old_pd);rxe_get (pd);
include/rdma/ib_umem.h +8 -0
@@ -179,6 +179,8 @@ void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabuf);void ib_umem_dmabuf_release (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>
@@ -239,5 +241,11 @@ static inline void ib_umem_dmabuf_unmap_pages(struct ib_umem_dmabuf *umem_dmabufstatic inline void ib_umem_dmabuf_release (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 */
Signature · 1 line
2.43.0