--- /dev/null
+From ee857ac8a1124a5c61f50a14a537eff9c6f0b30d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jan 2025 14:39:46 +0200
+Subject: IB/mlx5: Set and get correct qp_num for a DCT QP
+
+From: Mark Zhang <markzhang@nvidia.com>
+
+[ Upstream commit 12d044770e12c4205fa69535b4fa8a9981fea98f ]
+
+When a DCT QP is created on an active lag, it's dctc.port is assigned
+in a round-robin way, which is from 1 to dev->lag_port. In this case
+when querying this QP, we may get qp_attr.port_num > 2.
+Fix this by setting qp->port when modifying a DCT QP, and read port_num
+from qp->port instead of dctc.port when querying it.
+
+Fixes: 7c4b1ab9f167 ("IB/mlx5: Add DCT RoCE LAG support")
+Signed-off-by: Mark Zhang <markzhang@nvidia.com>
+Reviewed-by: Maher Sanalla <msanalla@nvidia.com>
+Link: https://patch.msgid.link/94c76bf0adbea997f87ffa27674e0a7118ad92a9.1737290358.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/qp.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index a43eba9d3572c..08d22db8dca91 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -4579,6 +4579,8 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+
+ set_id = mlx5_ib_get_counters_id(dev, attr->port_num - 1);
+ MLX5_SET(dctc, dctc, counter_set_id, set_id);
++
++ qp->port = attr->port_num;
+ } else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
+ struct mlx5_ib_modify_qp_resp resp = {};
+ u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {};
+@@ -5074,7 +5076,7 @@ static int mlx5_ib_dct_query_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *mqp,
+ }
+
+ if (qp_attr_mask & IB_QP_PORT)
+- qp_attr->port_num = MLX5_GET(dctc, dctc, port);
++ qp_attr->port_num = mqp->port;
+ if (qp_attr_mask & IB_QP_MIN_RNR_TIMER)
+ qp_attr->min_rnr_timer = MLX5_GET(dctc, dctc, min_rnr_nak);
+ if (qp_attr_mask & IB_QP_AV) {
+--
+2.39.5
+
--- /dev/null
+From 0fd8fa6a48e05bdb41f2d896f75adbb3d8b88ea0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 17:36:49 +0800
+Subject: landlock: Fix non-TCP sockets restriction
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>
+
+[ Upstream commit 854277e2cc8c75dc3c216c82e72523258fcf65b9 ]
+
+Use sk_is_tcp() to check if socket is TCP in bind(2) and connect(2)
+hooks.
+
+SMC, MPTCP, SCTP protocols are currently restricted by TCP access
+rights. The purpose of TCP access rights is to provide control over
+ports that can be used by userland to establish a TCP connection.
+Therefore, it is incorrect to deny bind(2) and connect(2) requests for a
+socket of another protocol.
+
+However, SMC, MPTCP and RDS implementations use TCP internal sockets to
+establish communication or even to exchange packets over a TCP
+connection [1]. Landlock rules that configure bind(2) and connect(2)
+usage for TCP sockets should not cover requests for sockets of such
+protocols. These protocols have different set of security issues and
+security properties, therefore, it is necessary to provide the userland
+with the ability to distinguish between them (eg. [2]).
+
+Control over TCP connection used by other protocols can be achieved with
+upcoming support of socket creation control [3].
+
+[1] https://lore.kernel.org/all/62336067-18c2-3493-d0ec-6dd6a6d3a1b5@huawei-partners.com/
+[2] https://lore.kernel.org/all/20241204.fahVio7eicim@digikod.net/
+[3] https://lore.kernel.org/all/20240904104824.1844082-1-ivanov.mikhail1@huawei-partners.com/
+
+Closes: https://github.com/landlock-lsm/linux/issues/40
+Fixes: fff69fb03dde ("landlock: Support network rules with TCP bind and connect")
+Signed-off-by: Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>
+Link: https://lore.kernel.org/r/20250205093651.1424339-2-ivanov.mikhail1@huawei-partners.com
+[mic: Format commit message to 72 columns]
+Signed-off-by: Mickaël Salaün <mic@digikod.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/landlock/net.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/security/landlock/net.c b/security/landlock/net.c
+index d5dcc4407a197..104b6c01fe503 100644
+--- a/security/landlock/net.c
++++ b/security/landlock/net.c
+@@ -63,8 +63,7 @@ static int current_check_access_socket(struct socket *const sock,
+ if (WARN_ON_ONCE(dom->num_layers < 1))
+ return -EACCES;
+
+- /* Checks if it's a (potential) TCP socket. */
+- if (sock->type != SOCK_STREAM)
++ if (!sk_is_tcp(sock->sk))
+ return 0;
+
+ /* Checks for minimal header length to safely read sa_family. */
+--
+2.39.5
+
--- /dev/null
+From 306f3ce15cb7bc53ff21c8d20edf8b6208ce65ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Feb 2025 14:59:03 -0500
+Subject: NFS: Adjust delegated timestamps for O_DIRECT reads and writes
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 88025c67fe3c025a0123bc7af50535b97f7af89a ]
+
+Adjust the timestamps if O_DIRECT is being combined with attribute
+delegations.
+
+Fixes: e12912d94137 ("NFSv4: Add support for delegated atime and mtime attributes")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/direct.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
+index 8f2aa2bf45659..6a6e758841336 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -56,6 +56,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/atomic.h>
+
++#include "delegation.h"
+ #include "internal.h"
+ #include "iostat.h"
+ #include "pnfs.h"
+@@ -286,6 +287,8 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
+ nfs_direct_count_bytes(dreq, hdr);
+ spin_unlock(&dreq->lock);
+
++ nfs_update_delegated_atime(dreq->inode);
++
+ while (!list_empty(&hdr->pages)) {
+ struct nfs_page *req = nfs_list_entry(hdr->pages.next);
+ struct page *page = req->wb_page;
+@@ -778,6 +781,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
+
+ spin_lock(&inode->i_lock);
+ nfs_direct_file_adjust_size_locked(inode, dreq->io_start, dreq->count);
++ nfs_update_delegated_mtime_locked(dreq->inode);
+ spin_unlock(&inode->i_lock);
+
+ while (!list_empty(&hdr->pages)) {
+--
+2.39.5
+
--- /dev/null
+From 1321c67fc068c270ac22d55313c363ed20c1d9c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Feb 2025 14:59:02 -0500
+Subject: NFS: O_DIRECT writes must check and adjust the file length
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit fcf857ee1958e9247298251f7615d0c76f1e9b38 ]
+
+While it is uncommon for delegations to be held while O_DIRECT writes
+are in progress, it is possible. The xfstests generic/647 and
+generic/729 both end up triggering that state, and end up failing due to
+the fact that the file size is not adjusted.
+
+Reported-by: Chuck Lever <chuck.lever@oracle.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=219738
+Cc: stable@vger.kernel.org
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Stable-dep-of: 88025c67fe3c ("NFS: Adjust delegated timestamps for O_DIRECT reads and writes")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/direct.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
+index b08dbe96bc579..8f2aa2bf45659 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -130,6 +130,20 @@ static void nfs_direct_truncate_request(struct nfs_direct_req *dreq,
+ dreq->count = req_start;
+ }
+
++static void nfs_direct_file_adjust_size_locked(struct inode *inode,
++ loff_t offset, size_t count)
++{
++ loff_t newsize = offset + (loff_t)count;
++ loff_t oldsize = i_size_read(inode);
++
++ if (newsize > oldsize) {
++ i_size_write(inode, newsize);
++ NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_SIZE;
++ trace_nfs_size_grow(inode, newsize);
++ nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
++ }
++}
++
+ /**
+ * nfs_swap_rw - NFS address space operation for swap I/O
+ * @iocb: target I/O control block
+@@ -740,6 +754,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
+ struct nfs_direct_req *dreq = hdr->dreq;
+ struct nfs_commit_info cinfo;
+ struct nfs_page *req = nfs_list_entry(hdr->pages.next);
++ struct inode *inode = dreq->inode;
+ int flags = NFS_ODIRECT_DONE;
+
+ trace_nfs_direct_write_completion(dreq);
+@@ -761,6 +776,10 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
+ }
+ spin_unlock(&dreq->lock);
+
++ spin_lock(&inode->i_lock);
++ nfs_direct_file_adjust_size_locked(inode, dreq->io_start, dreq->count);
++ spin_unlock(&inode->i_lock);
++
+ while (!list_empty(&hdr->pages)) {
+
+ req = nfs_list_entry(hdr->pages.next);
+--
+2.39.5
+
--- /dev/null
+From 9edd888627536937dfa4787ec12858e2bd66dda2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Feb 2025 15:00:09 -0500
+Subject: NFSv4: Fix a deadlock when recovering state on a sillyrenamed file
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 8f8df955f078e1a023ee55161935000a67651f38 ]
+
+If the file is sillyrenamed, and slated for delete on close, it is
+possible for a server reboot to triggeer an open reclaim, with can again
+race with the application call to close(). When that happens, the call
+to put_nfs_open_context() can trigger a synchronous delegreturn call
+which deadlocks because it is not marked as privileged.
+
+Instead, ensure that the call to nfs4_inode_return_delegation_on_close()
+catches the delegreturn, and schedules it asynchronously.
+
+Reported-by: Li Lingfeng <lilingfeng3@huawei.com>
+Fixes: adb4b42d19ae ("Return the delegation when deleting sillyrenamed files")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/delegation.c | 37 +++++++++++++++++++++++++++++++++++++
+ fs/nfs/delegation.h | 1 +
+ fs/nfs/nfs4proc.c | 3 +++
+ 3 files changed, 41 insertions(+)
+
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index 035ba52742a50..4db912f562305 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -780,6 +780,43 @@ int nfs4_inode_return_delegation(struct inode *inode)
+ return 0;
+ }
+
++/**
++ * nfs4_inode_set_return_delegation_on_close - asynchronously return a delegation
++ * @inode: inode to process
++ *
++ * This routine is called to request that the delegation be returned as soon
++ * as the file is closed. If the file is already closed, the delegation is
++ * immediately returned.
++ */
++void nfs4_inode_set_return_delegation_on_close(struct inode *inode)
++{
++ struct nfs_delegation *delegation;
++ struct nfs_delegation *ret = NULL;
++
++ if (!inode)
++ return;
++ rcu_read_lock();
++ delegation = nfs4_get_valid_delegation(inode);
++ if (!delegation)
++ goto out;
++ spin_lock(&delegation->lock);
++ if (!delegation->inode)
++ goto out_unlock;
++ if (list_empty(&NFS_I(inode)->open_files) &&
++ !test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
++ /* Refcount matched in nfs_end_delegation_return() */
++ ret = nfs_get_delegation(delegation);
++ } else
++ set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
++out_unlock:
++ spin_unlock(&delegation->lock);
++ if (ret)
++ nfs_clear_verifier_delegated(inode);
++out:
++ rcu_read_unlock();
++ nfs_end_delegation_return(inode, ret, 0);
++}
++
+ /**
+ * nfs4_inode_return_delegation_on_close - asynchronously return a delegation
+ * @inode: inode to process
+diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
+index 71524d34ed207..8ff5ab9c5c256 100644
+--- a/fs/nfs/delegation.h
++++ b/fs/nfs/delegation.h
+@@ -49,6 +49,7 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
+ unsigned long pagemod_limit, u32 deleg_type);
+ int nfs4_inode_return_delegation(struct inode *inode);
+ void nfs4_inode_return_delegation_on_close(struct inode *inode);
++void nfs4_inode_set_return_delegation_on_close(struct inode *inode);
+ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
+ void nfs_inode_evict_delegation(struct inode *inode);
+
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 405f17e6e0b45..e7bc99c69743c 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -3898,8 +3898,11 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx,
+
+ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
+ {
++ struct dentry *dentry = ctx->dentry;
+ if (ctx->state == NULL)
+ return;
++ if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
++ nfs4_inode_set_return_delegation_on_close(d_inode(dentry));
+ if (is_sync)
+ nfs4_close_sync(ctx->state, _nfs4_ctx_to_openmode(ctx));
+ else
+--
+2.39.5
+
--- /dev/null
+From d15e47d71bc6364310192d85fef40cbb0130a37e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Feb 2025 00:51:48 +0300
+Subject: ovl: fix UAF in ovl_dentry_update_reval by moving dput() in
+ ovl_link_up
+
+From: Vasiliy Kovalev <kovalev@altlinux.org>
+
+[ Upstream commit c84e125fff2615b4d9c259e762596134eddd2f27 ]
+
+The issue was caused by dput(upper) being called before
+ovl_dentry_update_reval(), while upper->d_flags was still
+accessed in ovl_dentry_remote().
+
+Move dput(upper) after its last use to prevent use-after-free.
+
+BUG: KASAN: slab-use-after-free in ovl_dentry_remote fs/overlayfs/util.c:162 [inline]
+BUG: KASAN: slab-use-after-free in ovl_dentry_update_reval+0xd2/0xf0 fs/overlayfs/util.c:167
+
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:114
+ print_address_description mm/kasan/report.c:377 [inline]
+ print_report+0xc3/0x620 mm/kasan/report.c:488
+ kasan_report+0xd9/0x110 mm/kasan/report.c:601
+ ovl_dentry_remote fs/overlayfs/util.c:162 [inline]
+ ovl_dentry_update_reval+0xd2/0xf0 fs/overlayfs/util.c:167
+ ovl_link_up fs/overlayfs/copy_up.c:610 [inline]
+ ovl_copy_up_one+0x2105/0x3490 fs/overlayfs/copy_up.c:1170
+ ovl_copy_up_flags+0x18d/0x200 fs/overlayfs/copy_up.c:1223
+ ovl_rename+0x39e/0x18c0 fs/overlayfs/dir.c:1136
+ vfs_rename+0xf84/0x20a0 fs/namei.c:4893
+...
+ </TASK>
+
+Fixes: b07d5cc93e1b ("ovl: update of dentry revalidate flags after copy up")
+Reported-by: syzbot+316db8a1191938280eb6@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=316db8a1191938280eb6
+Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
+Link: https://lore.kernel.org/r/20250214215148.761147-1-kovalev@altlinux.org
+Reviewed-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/overlayfs/copy_up.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index 0c28e5fa34077..d7310fcf38881 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -618,7 +618,6 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)
+ err = PTR_ERR(upper);
+ if (!IS_ERR(upper)) {
+ err = ovl_do_link(ofs, ovl_dentry_upper(c->dentry), udir, upper);
+- dput(upper);
+
+ if (!err) {
+ /* Restore timestamps on parent (best effort) */
+@@ -626,6 +625,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)
+ ovl_dentry_set_upper_alias(c->dentry);
+ ovl_dentry_update_reval(c->dentry, upper);
+ }
++ dput(upper);
+ }
+ inode_unlock(udir);
+ if (err)
+--
+2.39.5
+
--- /dev/null
+From 0a2f5037c9e5dec2212bf34a830cf40b61c3a1fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Feb 2025 00:21:23 -0800
+Subject: RDMA/bnxt_re: Add sanity checks on rdev validity
+
+From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+
+[ Upstream commit f0df225d12fcb049429fb5bf5122afe143c2dd15 ]
+
+There is a possibility that ulp_irq_stop and ulp_irq_start
+callbacks will be called when the device is in detached state.
+This can cause a crash due to NULL pointer dereference as
+the rdev is already freed.
+
+Fixes: cc5b9b48d447 ("RDMA/bnxt_re: Recover the device when FW error is detected")
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://patch.msgid.link/1738657285-23968-3-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
+index c143f273b7596..7368b0482bb87 100644
+--- a/drivers/infiniband/hw/bnxt_re/main.c
++++ b/drivers/infiniband/hw/bnxt_re/main.c
+@@ -321,6 +321,8 @@ static void bnxt_re_stop_irq(void *handle)
+ int indx;
+
+ rdev = en_info->rdev;
++ if (!rdev)
++ return;
+ rcfw = &rdev->rcfw;
+
+ for (indx = BNXT_RE_NQ_IDX; indx < rdev->nqr->num_msix; indx++) {
+@@ -341,6 +343,8 @@ static void bnxt_re_start_irq(void *handle, struct bnxt_msix_entry *ent)
+ int indx, rc;
+
+ rdev = en_info->rdev;
++ if (!rdev)
++ return;
+ msix_ent = rdev->nqr->msix_entries;
+ rcfw = &rdev->rcfw;
+ if (!ent) {
+@@ -2356,6 +2360,7 @@ static int bnxt_re_suspend(struct auxiliary_device *adev, pm_message_t state)
+ ibdev_info(&rdev->ibdev, "%s: L2 driver notified to stop en_state 0x%lx",
+ __func__, en_dev->en_state);
+ bnxt_re_remove_device(rdev, BNXT_RE_PRE_RECOVERY_REMOVE, adev);
++ bnxt_re_update_en_info_rdev(NULL, en_info, adev);
+ mutex_unlock(&bnxt_re_mutex);
+
+ return 0;
+--
+2.39.5
+
--- /dev/null
+From ab30486eb656ea09d6f0f4181f55e243db27af21 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jan 2025 10:18:13 -0800
+Subject: RDMA/bnxt_re: Allocate dev_attr information dynamically
+
+From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+
+[ Upstream commit 9264cd6aa8f194753507cb6e1f444141e7c79f48 ]
+
+In order to optimize the size of driver private structure,
+the memory for dev_attr is allocated dynamically during the
+chip context initialization. In order to make certain runtime
+decisions, store dev_attr in the qplib_res structure.
+
+Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://patch.msgid.link/1736446693-6692-3-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 8238c7bd8420 ("RDMA/bnxt_re: Fix the statistics for Gen P7 VF")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/bnxt_re.h | 2 +-
+ drivers/infiniband/hw/bnxt_re/hw_counters.c | 2 +-
+ drivers/infiniband/hw/bnxt_re/ib_verbs.c | 38 ++++++++++-----------
+ drivers/infiniband/hw/bnxt_re/main.c | 36 ++++++++++++-------
+ drivers/infiniband/hw/bnxt_re/qplib_res.c | 7 ++--
+ drivers/infiniband/hw/bnxt_re/qplib_res.h | 4 +--
+ drivers/infiniband/hw/bnxt_re/qplib_sp.c | 4 +--
+ drivers/infiniband/hw/bnxt_re/qplib_sp.h | 3 +-
+ 8 files changed, 51 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+index 2975b11b79bf7..22c98c155bd3c 100644
+--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
++++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+@@ -204,7 +204,7 @@ struct bnxt_re_dev {
+ struct bnxt_re_nq_record *nqr;
+
+ /* Device Resources */
+- struct bnxt_qplib_dev_attr dev_attr;
++ struct bnxt_qplib_dev_attr *dev_attr;
+ struct bnxt_qplib_ctx qplib_ctx;
+ struct bnxt_qplib_res qplib_res;
+ struct bnxt_qplib_dpi dpi_privileged;
+diff --git a/drivers/infiniband/hw/bnxt_re/hw_counters.c b/drivers/infiniband/hw/bnxt_re/hw_counters.c
+index 1e63f80917483..656c150e38e6f 100644
+--- a/drivers/infiniband/hw/bnxt_re/hw_counters.c
++++ b/drivers/infiniband/hw/bnxt_re/hw_counters.c
+@@ -357,7 +357,7 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
+ goto done;
+ }
+ bnxt_re_copy_err_stats(rdev, stats, err_s);
+- if (_is_ext_stats_supported(rdev->dev_attr.dev_cap_flags) &&
++ if (_is_ext_stats_supported(rdev->dev_attr->dev_cap_flags) &&
+ !rdev->is_virtfn) {
+ rc = bnxt_re_get_ext_stat(rdev, stats);
+ if (rc) {
+diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+index 1ff2e176b0369..4b61867188c4c 100644
+--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+@@ -161,7 +161,7 @@ static int __qp_access_flags_to_ib(struct bnxt_qplib_chip_ctx *cctx, u8 qflags)
+ static void bnxt_re_check_and_set_relaxed_ordering(struct bnxt_re_dev *rdev,
+ struct bnxt_qplib_mrw *qplib_mr)
+ {
+- if (_is_relaxed_ordering_supported(rdev->dev_attr.dev_cap_flags2) &&
++ if (_is_relaxed_ordering_supported(rdev->dev_attr->dev_cap_flags2) &&
+ pcie_relaxed_ordering_enabled(rdev->en_dev->pdev))
+ qplib_mr->flags |= CMDQ_REGISTER_MR_FLAGS_ENABLE_RO;
+ }
+@@ -186,7 +186,7 @@ int bnxt_re_query_device(struct ib_device *ibdev,
+ struct ib_udata *udata)
+ {
+ struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
+- struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
++ struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
+
+ memset(ib_attr, 0, sizeof(*ib_attr));
+ memcpy(&ib_attr->fw_ver, dev_attr->fw_ver,
+@@ -275,7 +275,7 @@ int bnxt_re_query_port(struct ib_device *ibdev, u32 port_num,
+ struct ib_port_attr *port_attr)
+ {
+ struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
+- struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
++ struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
+ int rc;
+
+ memset(port_attr, 0, sizeof(*port_attr));
+@@ -333,8 +333,8 @@ void bnxt_re_query_fw_str(struct ib_device *ibdev, char *str)
+ struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
+
+ snprintf(str, IB_FW_VERSION_NAME_MAX, "%d.%d.%d.%d",
+- rdev->dev_attr.fw_ver[0], rdev->dev_attr.fw_ver[1],
+- rdev->dev_attr.fw_ver[2], rdev->dev_attr.fw_ver[3]);
++ rdev->dev_attr->fw_ver[0], rdev->dev_attr->fw_ver[1],
++ rdev->dev_attr->fw_ver[2], rdev->dev_attr->fw_ver[3]);
+ }
+
+ int bnxt_re_query_pkey(struct ib_device *ibdev, u32 port_num,
+@@ -585,7 +585,7 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd)
+ mr->qplib_mr.pd = &pd->qplib_pd;
+ mr->qplib_mr.type = CMDQ_ALLOCATE_MRW_MRW_FLAGS_PMR;
+ mr->qplib_mr.access_flags = __from_ib_access_flags(mr_access_flags);
+- if (!_is_alloc_mr_unified(rdev->dev_attr.dev_cap_flags)) {
++ if (!_is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)) {
+ rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mr->qplib_mr);
+ if (rc) {
+ ibdev_err(&rdev->ibdev, "Failed to alloc fence-HW-MR\n");
+@@ -1057,7 +1057,7 @@ static int bnxt_re_setup_swqe_size(struct bnxt_re_qp *qp,
+ rdev = qp->rdev;
+ qplqp = &qp->qplib_qp;
+ sq = &qplqp->sq;
+- dev_attr = &rdev->dev_attr;
++ dev_attr = rdev->dev_attr;
+
+ align = sizeof(struct sq_send_hdr);
+ ilsize = ALIGN(init_attr->cap.max_inline_data, align);
+@@ -1277,7 +1277,7 @@ static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp,
+ rdev = qp->rdev;
+ qplqp = &qp->qplib_qp;
+ rq = &qplqp->rq;
+- dev_attr = &rdev->dev_attr;
++ dev_attr = rdev->dev_attr;
+
+ if (init_attr->srq) {
+ struct bnxt_re_srq *srq;
+@@ -1314,7 +1314,7 @@ static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp)
+
+ rdev = qp->rdev;
+ qplqp = &qp->qplib_qp;
+- dev_attr = &rdev->dev_attr;
++ dev_attr = rdev->dev_attr;
+
+ if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) {
+ qplqp->rq.max_sge = dev_attr->max_qp_sges;
+@@ -1340,7 +1340,7 @@ static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
+ rdev = qp->rdev;
+ qplqp = &qp->qplib_qp;
+ sq = &qplqp->sq;
+- dev_attr = &rdev->dev_attr;
++ dev_attr = rdev->dev_attr;
+
+ sq->max_sge = init_attr->cap.max_send_sge;
+ entries = init_attr->cap.max_send_wr;
+@@ -1393,7 +1393,7 @@ static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp,
+
+ rdev = qp->rdev;
+ qplqp = &qp->qplib_qp;
+- dev_attr = &rdev->dev_attr;
++ dev_attr = rdev->dev_attr;
+
+ if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) {
+ entries = bnxt_re_init_depth(init_attr->cap.max_send_wr + 1, uctx);
+@@ -1442,7 +1442,7 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
+
+ rdev = qp->rdev;
+ qplqp = &qp->qplib_qp;
+- dev_attr = &rdev->dev_attr;
++ dev_attr = rdev->dev_attr;
+
+ /* Setup misc params */
+ ether_addr_copy(qplqp->smac, rdev->netdev->dev_addr);
+@@ -1612,7 +1612,7 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
+ ib_pd = ib_qp->pd;
+ pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
+ rdev = pd->rdev;
+- dev_attr = &rdev->dev_attr;
++ dev_attr = rdev->dev_attr;
+ qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
+
+ uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
+@@ -1840,7 +1840,7 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
+ ib_pd = ib_srq->pd;
+ pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
+ rdev = pd->rdev;
+- dev_attr = &rdev->dev_attr;
++ dev_attr = rdev->dev_attr;
+ srq = container_of(ib_srq, struct bnxt_re_srq, ib_srq);
+
+ if (srq_init_attr->attr.max_wr >= dev_attr->max_srq_wqes) {
+@@ -2044,7 +2044,7 @@ int bnxt_re_modify_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr,
+ {
+ struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp);
+ struct bnxt_re_dev *rdev = qp->rdev;
+- struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
++ struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
+ enum ib_qp_state curr_qp_state, new_qp_state;
+ int rc, entries;
+ unsigned int flags;
+@@ -3091,7 +3091,7 @@ int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
+ struct ib_udata *udata = &attrs->driver_udata;
+ struct bnxt_re_ucontext *uctx =
+ rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
+- struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
++ struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
+ struct bnxt_qplib_chip_ctx *cctx;
+ int cqe = attr->cqe;
+ int rc, entries;
+@@ -3226,7 +3226,7 @@ int bnxt_re_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
+
+ cq = container_of(ibcq, struct bnxt_re_cq, ib_cq);
+ rdev = cq->rdev;
+- dev_attr = &rdev->dev_attr;
++ dev_attr = rdev->dev_attr;
+ if (!ibcq->uobject) {
+ ibdev_err(&rdev->ibdev, "Kernel CQ Resize not supported");
+ return -EOPNOTSUPP;
+@@ -4199,7 +4199,7 @@ static struct ib_mr *__bnxt_re_user_reg_mr(struct ib_pd *ib_pd, u64 length, u64
+ mr->qplib_mr.access_flags = __from_ib_access_flags(mr_access_flags);
+ mr->qplib_mr.type = CMDQ_ALLOCATE_MRW_MRW_FLAGS_MR;
+
+- if (!_is_alloc_mr_unified(rdev->dev_attr.dev_cap_flags)) {
++ if (!_is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)) {
+ rc = bnxt_qplib_alloc_mrw(&rdev->qplib_res, &mr->qplib_mr);
+ if (rc) {
+ ibdev_err(&rdev->ibdev, "Failed to allocate MR rc = %d", rc);
+@@ -4291,7 +4291,7 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
+ struct bnxt_re_ucontext *uctx =
+ container_of(ctx, struct bnxt_re_ucontext, ib_uctx);
+ struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
+- struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
++ struct bnxt_qplib_dev_attr *dev_attr = rdev->dev_attr;
+ struct bnxt_re_user_mmap_entry *entry;
+ struct bnxt_re_uctx_resp resp = {};
+ struct bnxt_re_uctx_req ureq = {};
+diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
+index 7368b0482bb87..b29687ec2ea31 100644
+--- a/drivers/infiniband/hw/bnxt_re/main.c
++++ b/drivers/infiniband/hw/bnxt_re/main.c
+@@ -153,6 +153,10 @@ static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
+
+ if (!rdev->chip_ctx)
+ return;
++
++ kfree(rdev->dev_attr);
++ rdev->dev_attr = NULL;
++
+ chip_ctx = rdev->chip_ctx;
+ rdev->chip_ctx = NULL;
+ rdev->rcfw.res = NULL;
+@@ -166,7 +170,7 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)
+ {
+ struct bnxt_qplib_chip_ctx *chip_ctx;
+ struct bnxt_en_dev *en_dev;
+- int rc;
++ int rc = -ENOMEM;
+
+ en_dev = rdev->en_dev;
+
+@@ -182,7 +186,10 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)
+
+ rdev->qplib_res.cctx = rdev->chip_ctx;
+ rdev->rcfw.res = &rdev->qplib_res;
+- rdev->qplib_res.dattr = &rdev->dev_attr;
++ rdev->dev_attr = kzalloc(sizeof(*rdev->dev_attr), GFP_KERNEL);
++ if (!rdev->dev_attr)
++ goto free_chip_ctx;
++ rdev->qplib_res.dattr = rdev->dev_attr;
+ rdev->qplib_res.is_vf = BNXT_EN_VF(en_dev);
+ rdev->qplib_res.en_dev = en_dev;
+
+@@ -190,16 +197,20 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)
+
+ bnxt_re_set_db_offset(rdev);
+ rc = bnxt_qplib_map_db_bar(&rdev->qplib_res);
+- if (rc) {
+- kfree(rdev->chip_ctx);
+- rdev->chip_ctx = NULL;
+- return rc;
+- }
++ if (rc)
++ goto free_dev_attr;
+
+ if (bnxt_qplib_determine_atomics(en_dev->pdev))
+ ibdev_info(&rdev->ibdev,
+ "platform doesn't support global atomics.");
+ return 0;
++free_dev_attr:
++ kfree(rdev->dev_attr);
++ rdev->dev_attr = NULL;
++free_chip_ctx:
++ kfree(rdev->chip_ctx);
++ rdev->chip_ctx = NULL;
++ return rc;
+ }
+
+ /* SR-IOV helper functions */
+@@ -221,7 +232,7 @@ static void bnxt_re_limit_pf_res(struct bnxt_re_dev *rdev)
+ struct bnxt_qplib_ctx *ctx;
+ int i;
+
+- attr = &rdev->dev_attr;
++ attr = rdev->dev_attr;
+ ctx = &rdev->qplib_ctx;
+
+ ctx->qpc_count = min_t(u32, BNXT_RE_MAX_QPC_COUNT,
+@@ -235,7 +246,7 @@ static void bnxt_re_limit_pf_res(struct bnxt_re_dev *rdev)
+ if (!bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))
+ for (i = 0; i < MAX_TQM_ALLOC_REQ; i++)
+ rdev->qplib_ctx.tqm_ctx.qcount[i] =
+- rdev->dev_attr.tqm_alloc_reqs[i];
++ rdev->dev_attr->tqm_alloc_reqs[i];
+ }
+
+ static void bnxt_re_limit_vf_res(struct bnxt_qplib_ctx *qplib_ctx, u32 num_vf)
+@@ -1631,12 +1642,11 @@ static int bnxt_re_alloc_res(struct bnxt_re_dev *rdev)
+
+ /* Configure and allocate resources for qplib */
+ rdev->qplib_res.rcfw = &rdev->rcfw;
+- rc = bnxt_qplib_get_dev_attr(&rdev->rcfw, &rdev->dev_attr);
++ rc = bnxt_qplib_get_dev_attr(&rdev->rcfw);
+ if (rc)
+ goto fail;
+
+- rc = bnxt_qplib_alloc_res(&rdev->qplib_res, rdev->en_dev->pdev,
+- rdev->netdev, &rdev->dev_attr);
++ rc = bnxt_qplib_alloc_res(&rdev->qplib_res, rdev->netdev);
+ if (rc)
+ goto fail;
+
+@@ -2036,7 +2046,7 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 op_type)
+ rdev->pacing.dbr_pacing = false;
+ }
+ }
+- rc = bnxt_qplib_get_dev_attr(&rdev->rcfw, &rdev->dev_attr);
++ rc = bnxt_qplib_get_dev_attr(&rdev->rcfw);
+ if (rc)
+ goto disable_rcfw;
+
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c
+index 96ceec1e8199a..02922a0987ad7 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c
+@@ -876,14 +876,13 @@ void bnxt_qplib_free_res(struct bnxt_qplib_res *res)
+ bnxt_qplib_free_dpi_tbl(res, &res->dpi_tbl);
+ }
+
+-int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev,
+- struct net_device *netdev,
+- struct bnxt_qplib_dev_attr *dev_attr)
++int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct net_device *netdev)
+ {
++ struct bnxt_qplib_dev_attr *dev_attr;
+ int rc;
+
+- res->pdev = pdev;
+ res->netdev = netdev;
++ dev_attr = res->dattr;
+
+ rc = bnxt_qplib_alloc_sgid_tbl(res, &res->sgid_tbl, dev_attr->max_sgid);
+ if (rc)
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h
+index cbfc49a1a56d7..be5d907a036b6 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h
+@@ -424,9 +424,7 @@ int bnxt_qplib_dealloc_dpi(struct bnxt_qplib_res *res,
+ void bnxt_qplib_cleanup_res(struct bnxt_qplib_res *res);
+ int bnxt_qplib_init_res(struct bnxt_qplib_res *res);
+ void bnxt_qplib_free_res(struct bnxt_qplib_res *res);
+-int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct pci_dev *pdev,
+- struct net_device *netdev,
+- struct bnxt_qplib_dev_attr *dev_attr);
++int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct net_device *netdev);
+ void bnxt_qplib_free_ctx(struct bnxt_qplib_res *res,
+ struct bnxt_qplib_ctx *ctx);
+ int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res,
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+index 9df3e3271577d..2e09616736bc7 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+@@ -88,9 +88,9 @@ static void bnxt_qplib_query_version(struct bnxt_qplib_rcfw *rcfw,
+ fw_ver[3] = resp.fw_rsvd;
+ }
+
+-int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
+- struct bnxt_qplib_dev_attr *attr)
++int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw)
+ {
++ struct bnxt_qplib_dev_attr *attr = rcfw->res->dattr;
+ struct creq_query_func_resp resp = {};
+ struct bnxt_qplib_cmdqmsg msg = {};
+ struct creq_query_func_resp_sb *sb;
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
+index e6beeb514b7dd..a1878eec7ba62 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
+@@ -325,8 +325,7 @@ int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
+ int bnxt_qplib_update_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
+ struct bnxt_qplib_gid *gid, u16 gid_idx,
+ const u8 *smac);
+-int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
+- struct bnxt_qplib_dev_attr *attr);
++int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw);
+ int bnxt_qplib_set_func_resources(struct bnxt_qplib_res *res,
+ struct bnxt_qplib_rcfw *rcfw,
+ struct bnxt_qplib_ctx *ctx);
+--
+2.39.5
+
--- /dev/null
+From 41cc26394ff51c0f5deb6f0a2fb4b840094ad1aa Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 22 Feb 2025 07:20:21 -0800
+Subject: RDMA/bnxt_re: Fix the page details for the srq created by kernel
+ consumers
+
+From: Kashyap Desai <kashyap.desai@broadcom.com>
+
+[ Upstream commit b66535356a4834a234f99e16a97eb51f2c6c5a7d ]
+
+While using nvme target with use_srq on, below kernel panic is noticed.
+
+[ 549.698111] bnxt_en 0000:41:00.0 enp65s0np0: FEC autoneg off encoding: Clause 91 RS(544,514)
+[ 566.393619] Oops: divide error: 0000 [#1] PREEMPT SMP NOPTI
+..
+[ 566.393799] <TASK>
+[ 566.393807] ? __die_body+0x1a/0x60
+[ 566.393823] ? die+0x38/0x60
+[ 566.393835] ? do_trap+0xe4/0x110
+[ 566.393847] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
+[ 566.393867] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
+[ 566.393881] ? do_error_trap+0x7c/0x120
+[ 566.393890] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
+[ 566.393911] ? exc_divide_error+0x34/0x50
+[ 566.393923] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
+[ 566.393939] ? asm_exc_divide_error+0x16/0x20
+[ 566.393966] ? bnxt_qplib_alloc_init_hwq+0x1d4/0x580 [bnxt_re]
+[ 566.393997] bnxt_qplib_create_srq+0xc9/0x340 [bnxt_re]
+[ 566.394040] bnxt_re_create_srq+0x335/0x3b0 [bnxt_re]
+[ 566.394057] ? srso_return_thunk+0x5/0x5f
+[ 566.394068] ? __init_swait_queue_head+0x4a/0x60
+[ 566.394090] ib_create_srq_user+0xa7/0x150 [ib_core]
+[ 566.394147] nvmet_rdma_queue_connect+0x7d0/0xbe0 [nvmet_rdma]
+[ 566.394174] ? lock_release+0x22c/0x3f0
+[ 566.394187] ? srso_return_thunk+0x5/0x5f
+
+Page size and shift info is set only for the user space SRQs.
+Set page size and page shift for kernel space SRQs also.
+
+Fixes: 0c4dcd602817 ("RDMA/bnxt_re: Refactor hardware queue memory allocation")
+Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://patch.msgid.link/1740237621-29291-1-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/ib_verbs.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+index 4b61867188c4c..0ed62d3e494c0 100644
+--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+@@ -1872,6 +1872,8 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
+ srq->qplib_srq.threshold = srq_init_attr->attr.srq_limit;
+ srq->srq_limit = srq_init_attr->attr.srq_limit;
+ srq->qplib_srq.eventq_hw_ring_id = rdev->nqr->nq[0].ring_id;
++ srq->qplib_srq.sg_info.pgsize = PAGE_SIZE;
++ srq->qplib_srq.sg_info.pgshft = PAGE_SHIFT;
+ nq = &rdev->nqr->nq[0];
+
+ if (udata) {
+--
+2.39.5
+
--- /dev/null
+From 9d1cf1fa588436db6358240ec7e541d7cad8c57e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Feb 2025 00:21:25 -0800
+Subject: RDMA/bnxt_re: Fix the statistics for Gen P7 VF
+
+From: Selvin Xavier <selvin.xavier@broadcom.com>
+
+[ Upstream commit 8238c7bd84209c8216b1381ab0dbe6db9e203769 ]
+
+Gen P7 VF support the extended stats and is prevented
+by a VF check. Fix the check to issue the FW command
+for GenP7 VFs also.
+
+Fixes: 1801d87b3598 ("RDMA/bnxt_re: Support new 5760X P7 devices")
+Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
+Link: https://patch.msgid.link/1738657285-23968-5-git-send-email-selvin.xavier@broadcom.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/bnxt_re/hw_counters.c | 4 ++--
+ drivers/infiniband/hw/bnxt_re/qplib_res.h | 8 ++++++++
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/bnxt_re/hw_counters.c b/drivers/infiniband/hw/bnxt_re/hw_counters.c
+index 656c150e38e6f..f51adb0a97e66 100644
+--- a/drivers/infiniband/hw/bnxt_re/hw_counters.c
++++ b/drivers/infiniband/hw/bnxt_re/hw_counters.c
+@@ -357,8 +357,8 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
+ goto done;
+ }
+ bnxt_re_copy_err_stats(rdev, stats, err_s);
+- if (_is_ext_stats_supported(rdev->dev_attr->dev_cap_flags) &&
+- !rdev->is_virtfn) {
++ if (bnxt_ext_stats_supported(rdev->chip_ctx, rdev->dev_attr->dev_cap_flags,
++ rdev->is_virtfn)) {
+ rc = bnxt_re_get_ext_stat(rdev, stats);
+ if (rc) {
+ clear_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS,
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h
+index be5d907a036b6..711990232de1c 100644
+--- a/drivers/infiniband/hw/bnxt_re/qplib_res.h
++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h
+@@ -547,6 +547,14 @@ static inline bool _is_ext_stats_supported(u16 dev_cap_flags)
+ CREQ_QUERY_FUNC_RESP_SB_EXT_STATS;
+ }
+
++static inline int bnxt_ext_stats_supported(struct bnxt_qplib_chip_ctx *ctx,
++ u16 flags, bool virtfn)
++{
++ /* ext stats supported if cap flag is set AND is a PF OR a Thor2 VF */
++ return (_is_ext_stats_supported(flags) &&
++ ((virtfn && bnxt_qplib_is_chip_gen_p7(ctx)) || (!virtfn)));
++}
++
+ static inline bool _is_hw_retx_supported(u16 dev_cap_flags)
+ {
+ return dev_cap_flags &
+--
+2.39.5
+
--- /dev/null
+From 1e6f4df5c52a78015f0cf17051c34572da8ccfc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 8 Feb 2025 18:59:30 +0800
+Subject: RDMA/hns: Fix mbox timing out by adding retry mechanism
+
+From: Junxian Huang <huangjunxian6@hisilicon.com>
+
+[ Upstream commit 9747c0c7791d4a5a62018a0c9c563dd2e6f6c1c0 ]
+
+If a QP is modified to error state and a flush CQE process is triggered,
+the subsequent QP destruction mbox can still be successfully posted but
+will be blocked in HW until the flush CQE process finishes. This causes
+further mbox posting timeouts in driver. The blocking time is related
+to QP depth. Considering an extreme case where SQ depth and RQ depth
+are both 32K, the blocking time can reach about 135ms.
+
+This patch adds a retry mechanism for mbox posting. For each try, FW
+waits 15ms for HW to complete the previous mbox, otherwise return a
+timeout error code to driver. Counting other time consumption in FW,
+set 8 tries for mbox posting and a 5ms time gap before each retry to
+increase to a sufficient timeout limit.
+
+Fixes: 0425e3e6e0c7 ("RDMA/hns: Support flush cqe for hip08 in kernel space")
+Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com>
+Link: https://patch.msgid.link/20250208105930.522796-1-huangjunxian6@hisilicon.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 64 ++++++++++++++++------
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +
+ 2 files changed, 50 insertions(+), 16 deletions(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 0144e7210d05a..f5c3e560df58d 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -1286,10 +1286,8 @@ static u32 hns_roce_cmdq_tx_timeout(u16 opcode, u32 tx_timeout)
+ return tx_timeout;
+ }
+
+-static void hns_roce_wait_csq_done(struct hns_roce_dev *hr_dev, u16 opcode)
++static void hns_roce_wait_csq_done(struct hns_roce_dev *hr_dev, u32 tx_timeout)
+ {
+- struct hns_roce_v2_priv *priv = hr_dev->priv;
+- u32 tx_timeout = hns_roce_cmdq_tx_timeout(opcode, priv->cmq.tx_timeout);
+ u32 timeout = 0;
+
+ do {
+@@ -1299,8 +1297,9 @@ static void hns_roce_wait_csq_done(struct hns_roce_dev *hr_dev, u16 opcode)
+ } while (++timeout < tx_timeout);
+ }
+
+-static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
+- struct hns_roce_cmq_desc *desc, int num)
++static int __hns_roce_cmq_send_one(struct hns_roce_dev *hr_dev,
++ struct hns_roce_cmq_desc *desc,
++ int num, u32 tx_timeout)
+ {
+ struct hns_roce_v2_priv *priv = hr_dev->priv;
+ struct hns_roce_v2_cmq_ring *csq = &priv->cmq.csq;
+@@ -1309,8 +1308,6 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
+ int ret;
+ int i;
+
+- spin_lock_bh(&csq->lock);
+-
+ tail = csq->head;
+
+ for (i = 0; i < num; i++) {
+@@ -1324,22 +1321,17 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
+
+ atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CMDS_CNT]);
+
+- hns_roce_wait_csq_done(hr_dev, le16_to_cpu(desc->opcode));
++ hns_roce_wait_csq_done(hr_dev, tx_timeout);
+ if (hns_roce_cmq_csq_done(hr_dev)) {
+ ret = 0;
+ for (i = 0; i < num; i++) {
+ /* check the result of hardware write back */
+- desc[i] = csq->desc[tail++];
++ desc_ret = le16_to_cpu(csq->desc[tail++].retval);
+ if (tail == csq->desc_num)
+ tail = 0;
+-
+- desc_ret = le16_to_cpu(desc[i].retval);
+ if (likely(desc_ret == CMD_EXEC_SUCCESS))
+ continue;
+
+- dev_err_ratelimited(hr_dev->dev,
+- "Cmdq IO error, opcode = 0x%x, return = 0x%x.\n",
+- desc->opcode, desc_ret);
+ ret = hns_roce_cmd_err_convert_errno(desc_ret);
+ }
+ } else {
+@@ -1354,14 +1346,54 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
+ ret = -EAGAIN;
+ }
+
+- spin_unlock_bh(&csq->lock);
+-
+ if (ret)
+ atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CMDS_ERR_CNT]);
+
+ return ret;
+ }
+
++static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
++ struct hns_roce_cmq_desc *desc, int num)
++{
++ struct hns_roce_v2_priv *priv = hr_dev->priv;
++ struct hns_roce_v2_cmq_ring *csq = &priv->cmq.csq;
++ u16 opcode = le16_to_cpu(desc->opcode);
++ u32 tx_timeout = hns_roce_cmdq_tx_timeout(opcode, priv->cmq.tx_timeout);
++ u8 try_cnt = HNS_ROCE_OPC_POST_MB_TRY_CNT;
++ u32 rsv_tail;
++ int ret;
++ int i;
++
++ while (try_cnt) {
++ try_cnt--;
++
++ spin_lock_bh(&csq->lock);
++ rsv_tail = csq->head;
++ ret = __hns_roce_cmq_send_one(hr_dev, desc, num, tx_timeout);
++ if (opcode == HNS_ROCE_OPC_POST_MB && ret == -ETIME &&
++ try_cnt) {
++ spin_unlock_bh(&csq->lock);
++ mdelay(HNS_ROCE_OPC_POST_MB_RETRY_GAP_MSEC);
++ continue;
++ }
++
++ for (i = 0; i < num; i++) {
++ desc[i] = csq->desc[rsv_tail++];
++ if (rsv_tail == csq->desc_num)
++ rsv_tail = 0;
++ }
++ spin_unlock_bh(&csq->lock);
++ break;
++ }
++
++ if (ret)
++ dev_err_ratelimited(hr_dev->dev,
++ "Cmdq IO error, opcode = 0x%x, return = %d.\n",
++ opcode, ret);
++
++ return ret;
++}
++
+ static int hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
+ struct hns_roce_cmq_desc *desc, int num)
+ {
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index cbdbc9edbce6e..91a5665465ffb 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -230,6 +230,8 @@ enum hns_roce_opcode_type {
+ };
+
+ #define HNS_ROCE_OPC_POST_MB_TIMEOUT 35000
++#define HNS_ROCE_OPC_POST_MB_TRY_CNT 8
++#define HNS_ROCE_OPC_POST_MB_RETRY_GAP_MSEC 5
+ struct hns_roce_cmdq_tx_timeout_map {
+ u16 opcode;
+ u32 tx_timeout;
+--
+2.39.5
+
--- /dev/null
+From f859f7ea531c50739d0eb570f99c747b89b6909c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 02:30:05 -0800
+Subject: RDMA/mana_ib: Allocate PAGE aligned doorbell index
+
+From: Konstantin Taranov <kotaranov@microsoft.com>
+
+[ Upstream commit 29b7bb98234cc287cebef9bccf638c2e3f39be71 ]
+
+Allocate a PAGE aligned doorbell index to ensure each process gets a
+separate PAGE sized doorbell area space remapped to it in mana_ib_mmap
+
+Fixes: 0266a177631d ("RDMA/mana_ib: Add a driver for Microsoft Azure Network Adapter")
+Signed-off-by: Shiraz Saleem <shirazsaleem@microsoft.com>
+Signed-off-by: Konstantin Taranov <kotaranov@microsoft.com>
+Link: https://patch.msgid.link/1738751405-15041-1-git-send-email-kotaranov@linux.microsoft.com
+Reviewed-by: Long Li <longli@microsoft.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mana/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mana/main.c b/drivers/infiniband/hw/mana/main.c
+index 67c2d43135a8a..457cea6d99095 100644
+--- a/drivers/infiniband/hw/mana/main.c
++++ b/drivers/infiniband/hw/mana/main.c
+@@ -174,7 +174,7 @@ static int mana_gd_allocate_doorbell_page(struct gdma_context *gc,
+
+ req.resource_type = GDMA_RESOURCE_DOORBELL_PAGE;
+ req.num_resources = 1;
+- req.alignment = 1;
++ req.alignment = PAGE_SIZE / MANA_PAGE_SIZE;
+
+ /* Have GDMA start searching from 0 */
+ req.allocated_resources = 0;
+--
+2.39.5
+
--- /dev/null
+From 37813bd2c0e55506b9586643f95b861ad0cd19cd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Feb 2025 14:50:59 +0200
+Subject: RDMA/mlx5: Fix a race for DMABUF MR which can lead to CQE with error
+
+From: Yishai Hadas <yishaih@nvidia.com>
+
+[ Upstream commit cc668a11e6ac8adb0e016711080d3f314722cc91 ]
+
+This patch addresses a potential race condition for a DMABUF MR that can
+result in a CQE with an error on the UMR QP.
+
+During the __mlx5_ib_dereg_mr() flow, the following sequence of calls
+occurs:
+mlx5_revoke_mr()
+mlx5r_umr_revoke_mr()
+mlx5r_umr_post_send_wait()
+At this point, the lkey is freed from the hardware's perspective.
+
+However, concurrently, mlx5_ib_dmabuf_invalidate_cb() might be triggered
+by another task attempting to invalidate the MR having that freed lkey.
+
+Since the lkey has already been freed, this can lead to a CQE error,
+causing the UMR QP to enter an error state.
+
+To resolve this race condition, the dma_resv_lock() which was hold as
+part of the mlx5_ib_dmabuf_invalidate_cb() is now also acquired as part
+of the mlx5_revoke_mr() scope.
+
+Upon a successful revoke, we set umem_dmabuf->private which points to
+that MR to NULL, preventing any further invalidation attempts on its
+lkey.
+
+Fixes: e6fb246ccafb ("RDMA/mlx5: Consolidate MR destruction to mlx5_ib_dereg_mr()")
+Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
+Reviewed-by: Artemy Kovalyov <artemyko@mnvidia.com>
+Link: https://patch.msgid.link/70617067abbfaa0c816a2544c922e7f4346def58.1738587016.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/mr.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
+index bb02b6adbf2c2..0a3cbb14e1839 100644
+--- a/drivers/infiniband/hw/mlx5/mr.c
++++ b/drivers/infiniband/hw/mlx5/mr.c
+@@ -1550,7 +1550,7 @@ static void mlx5_ib_dmabuf_invalidate_cb(struct dma_buf_attachment *attach)
+
+ dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv);
+
+- if (!umem_dmabuf->sgt)
++ if (!umem_dmabuf->sgt || !mr)
+ return;
+
+ mlx5r_umr_update_mr_pas(mr, MLX5_IB_UPD_XLT_ZAP);
+@@ -2022,11 +2022,16 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
+ struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device);
+ struct mlx5_cache_ent *ent = mr->mmkey.cache_ent;
+ bool is_odp = is_odp_mr(mr);
++ bool is_odp_dma_buf = is_dmabuf_mr(mr) &&
++ !to_ib_umem_dmabuf(mr->umem)->pinned;
+ int ret = 0;
+
+ if (is_odp)
+ mutex_lock(&to_ib_umem_odp(mr->umem)->umem_mutex);
+
++ if (is_odp_dma_buf)
++ dma_resv_lock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv, NULL);
++
+ if (mr->mmkey.cacheable && !mlx5r_umr_revoke_mr(mr) && !cache_ent_find_and_store(dev, mr)) {
+ ent = mr->mmkey.cache_ent;
+ /* upon storing to a clean temp entry - schedule its cleanup */
+@@ -2054,6 +2059,12 @@ static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
+ mutex_unlock(&to_ib_umem_odp(mr->umem)->umem_mutex);
+ }
+
++ if (is_odp_dma_buf) {
++ if (!ret)
++ to_ib_umem_dmabuf(mr->umem)->private = NULL;
++ dma_resv_unlock(to_ib_umem_dmabuf(mr->umem)->attach->dmabuf->resv);
++ }
++
+ return ret;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From 4ceca425be2796ddc278701cd62f03251d43d39c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Feb 2025 14:51:43 +0200
+Subject: RDMA/mlx5: Fix a WARN during dereg_mr for DM type
+
+From: Yishai Hadas <yishaih@nvidia.com>
+
+[ Upstream commit abc7b3f1f056d69a8f11d6dceecc0c9549ace770 ]
+
+Memory regions (MR) of type DM (device memory) do not have an associated
+umem.
+
+In the __mlx5_ib_dereg_mr() -> mlx5_free_priv_descs() flow, the code
+incorrectly takes the wrong branch, attempting to call
+dma_unmap_single() on a DMA address that is not mapped.
+
+This results in a WARN [1], as shown below.
+
+The issue is resolved by properly accounting for the DM type and
+ensuring the correct branch is selected in mlx5_free_priv_descs().
+
+[1]
+WARNING: CPU: 12 PID: 1346 at drivers/iommu/dma-iommu.c:1230 iommu_dma_unmap_page+0x79/0x90
+Modules linked in: ip6table_mangle ip6table_nat ip6table_filter ip6_tables iptable_mangle xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat br_netfilter rpcsec_gss_krb5 auth_rpcgss oid_registry ovelay rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi ib_umad rdma_cm ib_ipoib iw_cm ib_cm mlx5_ib ib_uverbs ib_core fuse mlx5_core
+CPU: 12 UID: 0 PID: 1346 Comm: ibv_rc_pingpong Not tainted 6.12.0-rc7+ #1631
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+RIP: 0010:iommu_dma_unmap_page+0x79/0x90
+Code: 2b 49 3b 29 72 26 49 3b 69 08 73 20 4d 89 f0 44 89 e9 4c 89 e2 48 89 ee 48 89 df 5b 5d 41 5c 41 5d 41 5e 41 5f e9 07 b8 88 ff <0f> 0b 5b 5d 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc 66 0f 1f 44 00
+RSP: 0018:ffffc90001913a10 EFLAGS: 00010246
+RAX: 0000000000000000 RBX: ffff88810194b0a8 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000001
+RBP: ffff88810194b0a8 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000000
+FS: 00007f537abdd740(0000) GS:ffff88885fb00000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00007f537aeb8000 CR3: 000000010c248001 CR4: 0000000000372eb0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+<TASK>
+? __warn+0x84/0x190
+? iommu_dma_unmap_page+0x79/0x90
+? report_bug+0xf8/0x1c0
+? handle_bug+0x55/0x90
+? exc_invalid_op+0x13/0x60
+? asm_exc_invalid_op+0x16/0x20
+? iommu_dma_unmap_page+0x79/0x90
+dma_unmap_page_attrs+0xe6/0x290
+mlx5_free_priv_descs+0xb0/0xe0 [mlx5_ib]
+__mlx5_ib_dereg_mr+0x37e/0x520 [mlx5_ib]
+? _raw_spin_unlock_irq+0x24/0x40
+? wait_for_completion+0xfe/0x130
+? rdma_restrack_put+0x63/0xe0 [ib_core]
+ib_dereg_mr_user+0x5f/0x120 [ib_core]
+? lock_release+0xc6/0x280
+destroy_hw_idr_uobject+0x1d/0x60 [ib_uverbs]
+uverbs_destroy_uobject+0x58/0x1d0 [ib_uverbs]
+uobj_destroy+0x3f/0x70 [ib_uverbs]
+ib_uverbs_cmd_verbs+0x3e4/0xbb0 [ib_uverbs]
+? __pfx_uverbs_destroy_def_handler+0x10/0x10 [ib_uverbs]
+? lock_acquire+0xc1/0x2f0
+? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
+? ib_uverbs_ioctl+0x116/0x170 [ib_uverbs]
+? lock_release+0xc6/0x280
+ib_uverbs_ioctl+0xe7/0x170 [ib_uverbs]
+? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
+__x64_sys_ioctl+0x1b0/0xa70
+do_syscall_64+0x6b/0x140
+entry_SYSCALL_64_after_hwframe+0x76/0x7e
+RIP: 0033:0x7f537adaf17b
+Code: 0f 1e fa 48 8b 05 1d ad 0c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d ed ac 0c 00 f7 d8 64 89 01 48
+RSP: 002b:00007ffff218f0b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+RAX: ffffffffffffffda RBX: 00007ffff218f1d8 RCX: 00007f537adaf17b
+RDX: 00007ffff218f1c0 RSI: 00000000c0181b01 RDI: 0000000000000003
+RBP: 00007ffff218f1a0 R08: 00007f537aa8d010 R09: 0000561ee2e4f270
+R10: 00007f537aace3a8 R11: 0000000000000246 R12: 00007ffff218f190
+R13: 000000000000001c R14: 0000561ee2e4d7c0 R15: 00007ffff218f450
+</TASK>
+
+Fixes: f18ec4223117 ("RDMA/mlx5: Use a union inside mlx5_ib_mr")
+Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
+Link: https://patch.msgid.link/2039c22cfc3df02378747ba4d623a558b53fc263.1738587076.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/mr.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
+index 0a3cbb14e1839..753faa9ad06a8 100644
+--- a/drivers/infiniband/hw/mlx5/mr.c
++++ b/drivers/infiniband/hw/mlx5/mr.c
+@@ -1935,7 +1935,8 @@ mlx5_alloc_priv_descs(struct ib_device *device,
+ static void
+ mlx5_free_priv_descs(struct mlx5_ib_mr *mr)
+ {
+- if (!mr->umem && !mr->data_direct && mr->descs) {
++ if (!mr->umem && !mr->data_direct &&
++ mr->ibmr.type != IB_MR_TYPE_DM && mr->descs) {
+ struct ib_device *device = mr->ibmr.device;
+ int size = mr->max_descs * mr->desc_size;
+ struct mlx5_ib_dev *dev = to_mdev(device);
+--
+2.39.5
+
--- /dev/null
+From 7a4c9bbda7158de15c7b7b12e6501d94c1150485 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 13:32:39 +0200
+Subject: RDMA/mlx5: Fix AH static rate parsing
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ Upstream commit c534ffda781f44a1c6ac25ef6e0e444da38ca8af ]
+
+Previously static rate wasn't translated according to our PRM but simply
+used the 4 lower bytes.
+
+Correctly translate static rate value passed in AH creation attribute
+according to our PRM expected values.
+
+In addition change 800GB mapping to zero, which is the PRM
+specified value.
+
+Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters")
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Reviewed-by: Maor Gottlieb <maorg@nvidia.com>
+Link: https://patch.msgid.link/18ef4cc5396caf80728341eb74738cd777596f60.1739187089.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/ah.c | 3 ++-
+ drivers/infiniband/hw/mlx5/qp.c | 6 +++---
+ drivers/infiniband/hw/mlx5/qp.h | 1 +
+ 3 files changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/ah.c b/drivers/infiniband/hw/mlx5/ah.c
+index 505bc47fd575d..99036afb3aef0 100644
+--- a/drivers/infiniband/hw/mlx5/ah.c
++++ b/drivers/infiniband/hw/mlx5/ah.c
+@@ -67,7 +67,8 @@ static void create_ib_ah(struct mlx5_ib_dev *dev, struct mlx5_ib_ah *ah,
+ ah->av.tclass = grh->traffic_class;
+ }
+
+- ah->av.stat_rate_sl = (rdma_ah_get_static_rate(ah_attr) << 4);
++ ah->av.stat_rate_sl =
++ (mlx5r_ib_rate(dev, rdma_ah_get_static_rate(ah_attr)) << 4);
+
+ if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) {
+ if (init_attr->xmit_slave)
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index 08d22db8dca91..88724d15705d4 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -3447,11 +3447,11 @@ static int ib_to_mlx5_rate_map(u8 rate)
+ return 0;
+ }
+
+-static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate)
++int mlx5r_ib_rate(struct mlx5_ib_dev *dev, u8 rate)
+ {
+ u32 stat_rate_support;
+
+- if (rate == IB_RATE_PORT_CURRENT)
++ if (rate == IB_RATE_PORT_CURRENT || rate == IB_RATE_800_GBPS)
+ return 0;
+
+ if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_800_GBPS)
+@@ -3596,7 +3596,7 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
+ sizeof(grh->dgid.raw));
+ }
+
+- err = ib_rate_to_mlx5(dev, rdma_ah_get_static_rate(ah));
++ err = mlx5r_ib_rate(dev, rdma_ah_get_static_rate(ah));
+ if (err < 0)
+ return err;
+ MLX5_SET(ads, path, stat_rate, err);
+diff --git a/drivers/infiniband/hw/mlx5/qp.h b/drivers/infiniband/hw/mlx5/qp.h
+index b6ee7c3ee1ca1..2530e7730635f 100644
+--- a/drivers/infiniband/hw/mlx5/qp.h
++++ b/drivers/infiniband/hw/mlx5/qp.h
+@@ -56,4 +56,5 @@ int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn);
+ int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter);
+ int mlx5_ib_qp_event_init(void);
+ void mlx5_ib_qp_event_cleanup(void);
++int mlx5r_ib_rate(struct mlx5_ib_dev *dev, u8 rate);
+ #endif /* _MLX5_IB_QP_H */
+--
+2.39.5
+
--- /dev/null
+From de0a37ee8796c9b61beeeaae3c027b374f9cd867 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Feb 2025 08:47:10 +0200
+Subject: RDMA/mlx5: Fix bind QP error cleanup flow
+
+From: Patrisious Haddad <phaddad@nvidia.com>
+
+[ Upstream commit e1a0bdbdfdf08428f0ede5ae49c7f4139ac73ef5 ]
+
+When there is a failure during bind QP, the cleanup flow destroys the
+counter regardless if it is the one that created it or not, which is
+problematic since if it isn't the one that created it, that counter could
+still be in use.
+
+Fix that by destroying the counter only if it was created during this call.
+
+Fixes: 45842fc627c7 ("IB/mlx5: Support statistic q counter configuration")
+Signed-off-by: Patrisious Haddad <phaddad@nvidia.com>
+Reviewed-by: Mark Zhang <markzhang@nvidia.com>
+Link: https://patch.msgid.link/25dfefddb0ebefa668c32e06a94d84e3216257cf.1740033937.git.leon@kernel.org
+Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/counters.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c
+index 4f6c1968a2ee3..81cfa74147a18 100644
+--- a/drivers/infiniband/hw/mlx5/counters.c
++++ b/drivers/infiniband/hw/mlx5/counters.c
+@@ -546,6 +546,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,
+ struct ib_qp *qp)
+ {
+ struct mlx5_ib_dev *dev = to_mdev(qp->device);
++ bool new = false;
+ int err;
+
+ if (!counter->id) {
+@@ -560,6 +561,7 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,
+ return err;
+ counter->id =
+ MLX5_GET(alloc_q_counter_out, out, counter_set_id);
++ new = true;
+ }
+
+ err = mlx5_ib_qp_set_counter(qp, counter);
+@@ -569,8 +571,10 @@ static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,
+ return 0;
+
+ fail_set_counter:
+- mlx5_ib_counter_dealloc(counter);
+- counter->id = 0;
++ if (new) {
++ mlx5_ib_counter_dealloc(counter);
++ counter->id = 0;
++ }
+
+ return err;
+ }
+--
+2.39.5
+
--- /dev/null
+From f40756a4b8a9fd9fe636fb81d9f2ce027d7f25bb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Feb 2025 13:31:11 +0200
+Subject: RDMA/mlx5: Fix implicit ODP hang on parent deregistration
+
+From: Yishai Hadas <yishaih@nvidia.com>
+
+[ Upstream commit 3d8c6f26893d55fab218ad086719de1fc9bb86ba ]
+
+Fix the destroy_unused_implicit_child_mr() to prevent hanging during
+parent deregistration as of below [1].
+
+Upon entering destroy_unused_implicit_child_mr(), the reference count
+for the implicit MR parent is incremented using:
+refcount_inc_not_zero().
+
+A corresponding decrement must be performed if
+free_implicit_child_mr_work() is not called.
+
+The code has been updated to properly manage the reference count that
+was incremented.
+
+[1]
+INFO: task python3:2157 blocked for more than 120 seconds.
+Not tainted 6.12.0-rc7+ #1633
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+task:python3 state:D stack:0 pid:2157 tgid:2157 ppid:1685 flags:0x00000000
+Call Trace:
+<TASK>
+__schedule+0x420/0xd30
+schedule+0x47/0x130
+__mlx5_ib_dereg_mr+0x379/0x5d0 [mlx5_ib]
+? __pfx_autoremove_wake_function+0x10/0x10
+ib_dereg_mr_user+0x5f/0x120 [ib_core]
+? lock_release+0xc6/0x280
+destroy_hw_idr_uobject+0x1d/0x60 [ib_uverbs]
+uverbs_destroy_uobject+0x58/0x1d0 [ib_uverbs]
+uobj_destroy+0x3f/0x70 [ib_uverbs]
+ib_uverbs_cmd_verbs+0x3e4/0xbb0 [ib_uverbs]
+? __pfx_uverbs_destroy_def_handler+0x10/0x10 [ib_uverbs]
+? lock_acquire+0xc1/0x2f0
+? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
+? ib_uverbs_ioctl+0x116/0x170 [ib_uverbs]
+? lock_release+0xc6/0x280
+ib_uverbs_ioctl+0xe7/0x170 [ib_uverbs]
+? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
+ __x64_sys_ioctl+0x1b0/0xa70
+? kmem_cache_free+0x221/0x400
+do_syscall_64+0x6b/0x140
+entry_SYSCALL_64_after_hwframe+0x76/0x7e
+RIP: 0033:0x7f20f21f017b
+RSP: 002b:00007ffcfc4a77c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
+RAX: ffffffffffffffda RBX: 00007ffcfc4a78d8 RCX: 00007f20f21f017b
+RDX: 00007ffcfc4a78c0 RSI: 00000000c0181b01 RDI: 0000000000000003
+RBP: 00007ffcfc4a78a0 R08: 000056147d125190 R09: 00007f20f1f14c60
+R10: 0000000000000001 R11: 0000000000000246 R12: 00007ffcfc4a7890
+R13: 000000000000001c R14: 000056147d100fc0 R15: 00007f20e365c9d0
+</TASK>
+
+Fixes: d3d930411ce3 ("RDMA/mlx5: Fix implicit ODP use after free")
+Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
+Reviewed-by: Artemy Kovalyov <artemyko@nvidia.com>
+Link: https://patch.msgid.link/80f2fcd19952dfa7d9981d93fd6359b4471f8278.1739186929.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/odp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
+index 1d3bf56157702..b4e2a6f9cb9c3 100644
+--- a/drivers/infiniband/hw/mlx5/odp.c
++++ b/drivers/infiniband/hw/mlx5/odp.c
+@@ -242,6 +242,7 @@ static void destroy_unused_implicit_child_mr(struct mlx5_ib_mr *mr)
+ if (__xa_cmpxchg(&imr->implicit_children, idx, mr, NULL, GFP_KERNEL) !=
+ mr) {
+ xa_unlock(&imr->implicit_children);
++ mlx5r_deref_odp_mkey(&imr->mmkey);
+ return;
+ }
+
+--
+2.39.5
+
--- /dev/null
+From bd0213cbab0b888f59b5e601a2331f8083610f9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 19 Jan 2025 14:36:13 +0200
+Subject: RDMA/mlx5: Fix the recovery flow of the UMR QP
+
+From: Yishai Hadas <yishaih@nvidia.com>
+
+[ Upstream commit d97505baea64d93538b16baf14ce7b8c1fbad746 ]
+
+This patch addresses an issue in the recovery flow of the UMR QP,
+ensuring tasks do not get stuck, as highlighted by the call trace [1].
+
+During recovery, before transitioning the QP to the RESET state, the
+software must wait for all outstanding WRs to complete.
+
+Failing to do so can cause the firmware to skip sending some flushed
+CQEs with errors and simply discard them upon the RESET, as per the IB
+specification.
+
+This race condition can result in lost CQEs and tasks becoming stuck.
+
+To resolve this, the patch sends a final WR which serves only as a
+barrier before moving the QP state to RESET.
+
+Once a CQE is received for that final WR, it guarantees that no
+outstanding WRs remain, making it safe to transition the QP to RESET and
+subsequently back to RTS, restoring proper functionality.
+
+Note:
+For the barrier WR, we simply reuse the failed and ready WR.
+Since the QP is in an error state, it will only receive
+IB_WC_WR_FLUSH_ERR. However, as it serves only as a barrier we don't
+care about its status.
+
+[1]
+INFO: task rdma_resource_l:1922 blocked for more than 120 seconds.
+Tainted: G W 6.12.0-rc7+ #1626
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+task:rdma_resource_l state:D stack:0 pid:1922 tgid:1922 ppid:1369
+ flags:0x00004004
+Call Trace:
+<TASK>
+__schedule+0x420/0xd30
+schedule+0x47/0x130
+schedule_timeout+0x280/0x300
+? mark_held_locks+0x48/0x80
+? lockdep_hardirqs_on_prepare+0xe5/0x1a0
+wait_for_completion+0x75/0x130
+mlx5r_umr_post_send_wait+0x3c2/0x5b0 [mlx5_ib]
+? __pfx_mlx5r_umr_done+0x10/0x10 [mlx5_ib]
+mlx5r_umr_revoke_mr+0x93/0xc0 [mlx5_ib]
+__mlx5_ib_dereg_mr+0x299/0x520 [mlx5_ib]
+? _raw_spin_unlock_irq+0x24/0x40
+? wait_for_completion+0xfe/0x130
+? rdma_restrack_put+0x63/0xe0 [ib_core]
+ib_dereg_mr_user+0x5f/0x120 [ib_core]
+? lock_release+0xc6/0x280
+destroy_hw_idr_uobject+0x1d/0x60 [ib_uverbs]
+uverbs_destroy_uobject+0x58/0x1d0 [ib_uverbs]
+uobj_destroy+0x3f/0x70 [ib_uverbs]
+ib_uverbs_cmd_verbs+0x3e4/0xbb0 [ib_uverbs]
+? __pfx_uverbs_destroy_def_handler+0x10/0x10 [ib_uverbs]
+? __lock_acquire+0x64e/0x2080
+? mark_held_locks+0x48/0x80
+? find_held_lock+0x2d/0xa0
+? lock_acquire+0xc1/0x2f0
+? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
+? __fget_files+0xc3/0x1b0
+ib_uverbs_ioctl+0xe7/0x170 [ib_uverbs]
+? ib_uverbs_ioctl+0xcb/0x170 [ib_uverbs]
+__x64_sys_ioctl+0x1b0/0xa70
+do_syscall_64+0x6b/0x140
+entry_SYSCALL_64_after_hwframe+0x76/0x7e
+RIP: 0033:0x7f99c918b17b
+RSP: 002b:00007ffc766d0468 EFLAGS: 00000246 ORIG_RAX:
+ 0000000000000010
+RAX: ffffffffffffffda RBX: 00007ffc766d0578 RCX:
+ 00007f99c918b17b
+RDX: 00007ffc766d0560 RSI: 00000000c0181b01 RDI:
+ 0000000000000003
+RBP: 00007ffc766d0540 R08: 00007f99c8f99010 R09:
+ 000000000000bd7e
+R10: 00007f99c94c1c70 R11: 0000000000000246 R12:
+ 00007ffc766d0530
+R13: 000000000000001c R14: 0000000040246a80 R15:
+ 0000000000000000
+</TASK>
+
+Fixes: 158e71bb69e3 ("RDMA/mlx5: Add a umr recovery flow")
+Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
+Reviewed-by: Michael Guralnik <michaelgur@nvidia.com>
+Link: https://patch.msgid.link/27b51b92ec42dfb09d8096fcbd51878f397ce6ec.1737290141.git.leon@kernel.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/umr.c | 83 +++++++++++++++++++++-----------
+ 1 file changed, 56 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/infiniband/hw/mlx5/umr.c b/drivers/infiniband/hw/mlx5/umr.c
+index 887fd6fa3ba93..793f3c5c4d012 100644
+--- a/drivers/infiniband/hw/mlx5/umr.c
++++ b/drivers/infiniband/hw/mlx5/umr.c
+@@ -231,30 +231,6 @@ void mlx5r_umr_cleanup(struct mlx5_ib_dev *dev)
+ ib_dealloc_pd(dev->umrc.pd);
+ }
+
+-static int mlx5r_umr_recover(struct mlx5_ib_dev *dev)
+-{
+- struct umr_common *umrc = &dev->umrc;
+- struct ib_qp_attr attr;
+- int err;
+-
+- attr.qp_state = IB_QPS_RESET;
+- err = ib_modify_qp(umrc->qp, &attr, IB_QP_STATE);
+- if (err) {
+- mlx5_ib_dbg(dev, "Couldn't modify UMR QP\n");
+- goto err;
+- }
+-
+- err = mlx5r_umr_qp_rst2rts(dev, umrc->qp);
+- if (err)
+- goto err;
+-
+- umrc->state = MLX5_UMR_STATE_ACTIVE;
+- return 0;
+-
+-err:
+- umrc->state = MLX5_UMR_STATE_ERR;
+- return err;
+-}
+
+ static int mlx5r_umr_post_send(struct ib_qp *ibqp, u32 mkey, struct ib_cqe *cqe,
+ struct mlx5r_umr_wqe *wqe, bool with_data)
+@@ -302,6 +278,61 @@ static int mlx5r_umr_post_send(struct ib_qp *ibqp, u32 mkey, struct ib_cqe *cqe,
+ return err;
+ }
+
++static int mlx5r_umr_recover(struct mlx5_ib_dev *dev, u32 mkey,
++ struct mlx5r_umr_context *umr_context,
++ struct mlx5r_umr_wqe *wqe, bool with_data)
++{
++ struct umr_common *umrc = &dev->umrc;
++ struct ib_qp_attr attr;
++ int err;
++
++ mutex_lock(&umrc->lock);
++ /* Preventing any further WRs to be sent now */
++ if (umrc->state != MLX5_UMR_STATE_RECOVER) {
++ mlx5_ib_warn(dev, "UMR recovery encountered an unexpected state=%d\n",
++ umrc->state);
++ umrc->state = MLX5_UMR_STATE_RECOVER;
++ }
++ mutex_unlock(&umrc->lock);
++
++ /* Sending a final/barrier WR (the failed one) and wait for its completion.
++ * This will ensure that all the previous WRs got a completion before
++ * we set the QP state to RESET.
++ */
++ err = mlx5r_umr_post_send(umrc->qp, mkey, &umr_context->cqe, wqe,
++ with_data);
++ if (err) {
++ mlx5_ib_warn(dev, "UMR recovery post send failed, err %d\n", err);
++ goto err;
++ }
++
++ /* Since the QP is in an error state, it will only receive
++ * IB_WC_WR_FLUSH_ERR. However, as it serves only as a barrier
++ * we don't care about its status.
++ */
++ wait_for_completion(&umr_context->done);
++
++ attr.qp_state = IB_QPS_RESET;
++ err = ib_modify_qp(umrc->qp, &attr, IB_QP_STATE);
++ if (err) {
++ mlx5_ib_warn(dev, "Couldn't modify UMR QP to RESET, err=%d\n", err);
++ goto err;
++ }
++
++ err = mlx5r_umr_qp_rst2rts(dev, umrc->qp);
++ if (err) {
++ mlx5_ib_warn(dev, "Couldn't modify UMR QP to RTS, err=%d\n", err);
++ goto err;
++ }
++
++ umrc->state = MLX5_UMR_STATE_ACTIVE;
++ return 0;
++
++err:
++ umrc->state = MLX5_UMR_STATE_ERR;
++ return err;
++}
++
+ static void mlx5r_umr_done(struct ib_cq *cq, struct ib_wc *wc)
+ {
+ struct mlx5_ib_umr_context *context =
+@@ -366,9 +397,7 @@ static int mlx5r_umr_post_send_wait(struct mlx5_ib_dev *dev, u32 mkey,
+ mlx5_ib_warn(dev,
+ "reg umr failed (%u). Trying to recover and resubmit the flushed WQEs, mkey = %u\n",
+ umr_context.status, mkey);
+- mutex_lock(&umrc->lock);
+- err = mlx5r_umr_recover(dev);
+- mutex_unlock(&umrc->lock);
++ err = mlx5r_umr_recover(dev, mkey, &umr_context, wqe, with_data);
+ if (err)
+ mlx5_ib_warn(dev, "couldn't recover UMR, err %d\n",
+ err);
+--
+2.39.5
+
--- /dev/null
+From 7c67b6d2cbea5efcfb6e92805b57d24b6aa87fe9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Feb 2025 10:16:28 +0800
+Subject: scsi: core: Clear driver private data when retrying request
+
+From: Ye Bin <yebin10@huawei.com>
+
+[ Upstream commit dce5c4afd035e8090a26e5d776b1682c0e649683 ]
+
+After commit 1bad6c4a57ef ("scsi: zero per-cmd private driver data for each
+MQ I/O"), the xen-scsifront/virtio_scsi/snic drivers all removed code that
+explicitly zeroed driver-private command data.
+
+In combination with commit 464a00c9e0ad ("scsi: core: Kill DRIVER_SENSE"),
+after virtio_scsi performs a capacity expansion, the first request will
+return a unit attention to indicate that the capacity has changed. And then
+the original command is retried. As driver-private command data was not
+cleared, the request would return UA again and eventually time out and fail.
+
+Zero driver-private command data when a request is retried.
+
+Fixes: f7de50da1479 ("scsi: xen-scsifront: Remove code that zeroes driver-private command data")
+Fixes: c2bb87318baa ("scsi: virtio_scsi: Remove code that zeroes driver-private command data")
+Fixes: c3006a926468 ("scsi: snic: Remove code that zeroes driver-private command data")
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20250217021628.2929248-1-yebin@huaweicloud.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_lib.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 5f9b107ae267f..43766589bfc6e 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -1656,13 +1656,6 @@ static blk_status_t scsi_prepare_cmd(struct request *req)
+ if (in_flight)
+ __set_bit(SCMD_STATE_INFLIGHT, &cmd->state);
+
+- /*
+- * Only clear the driver-private command data if the LLD does not supply
+- * a function to initialize that data.
+- */
+- if (!shost->hostt->init_cmd_priv)
+- memset(cmd + 1, 0, shost->hostt->cmd_size);
+-
+ cmd->prot_op = SCSI_PROT_NORMAL;
+ if (blk_rq_bytes(req))
+ cmd->sc_data_direction = rq_dma_dir(req);
+@@ -1829,6 +1822,13 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx,
+ if (!scsi_host_queue_ready(q, shost, sdev, cmd))
+ goto out_dec_target_busy;
+
++ /*
++ * Only clear the driver-private command data if the LLD does not supply
++ * a function to initialize that data.
++ */
++ if (shost->hostt->cmd_size && !shost->hostt->init_cmd_priv)
++ memset(cmd + 1, 0, shost->hostt->cmd_size);
++
+ if (!(req->rq_flags & RQF_DONTPREP)) {
+ ret = scsi_prepare_cmd(req);
+ if (ret != BLK_STS_OK)
+--
+2.39.5
+
--- /dev/null
+From 6087445080212aee14927669f83fbc10f1d0e021 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Feb 2025 14:43:44 -0800
+Subject: scsi: ufs: core: Fix ufshcd_is_ufs_dev_busy() and
+ ufshcd_eh_timed_out()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit 4fa382be430421e1445f9c95c4dc9b7e0949ae8a ]
+
+ufshcd_is_ufs_dev_busy(), ufshcd_print_host_state() and
+ufshcd_eh_timed_out() are used in both modes (legacy mode and MCQ mode).
+hba->outstanding_reqs only represents the outstanding requests in legacy
+mode. Hence, change hba->outstanding_reqs into scsi_host_busy(hba->host) in
+these functions.
+
+Fixes: eacb139b77ff ("scsi: ufs: core: mcq: Enable multi-circular queue")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20250214224352.3025151-1-bvanassche@acm.org
+Reviewed-by: Peter Wang <peter.wang@mediatek.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index 56b32d245c2ee..37b626e128f95 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -266,7 +266,7 @@ static bool ufshcd_has_pending_tasks(struct ufs_hba *hba)
+
+ static bool ufshcd_is_ufs_dev_busy(struct ufs_hba *hba)
+ {
+- return hba->outstanding_reqs || ufshcd_has_pending_tasks(hba);
++ return scsi_host_busy(hba->host) || ufshcd_has_pending_tasks(hba);
+ }
+
+ static const struct ufs_dev_quirk ufs_fixups[] = {
+@@ -628,8 +628,8 @@ static void ufshcd_print_host_state(struct ufs_hba *hba)
+ const struct scsi_device *sdev_ufs = hba->ufs_device_wlun;
+
+ dev_err(hba->dev, "UFS Host state=%d\n", hba->ufshcd_state);
+- dev_err(hba->dev, "outstanding reqs=0x%lx tasks=0x%lx\n",
+- hba->outstanding_reqs, hba->outstanding_tasks);
++ dev_err(hba->dev, "%d outstanding reqs, tasks=0x%lx\n",
++ scsi_host_busy(hba->host), hba->outstanding_tasks);
+ dev_err(hba->dev, "saved_err=0x%x, saved_uic_err=0x%x\n",
+ hba->saved_err, hba->saved_uic_err);
+ dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n",
+@@ -8944,7 +8944,7 @@ static enum scsi_timeout_action ufshcd_eh_timed_out(struct scsi_cmnd *scmd)
+ dev_info(hba->dev, "%s() finished; outstanding_tasks = %#lx.\n",
+ __func__, hba->outstanding_tasks);
+
+- return hba->outstanding_reqs ? SCSI_EH_RESET_TIMER : SCSI_EH_DONE;
++ return scsi_host_busy(hba->host) ? SCSI_EH_RESET_TIMER : SCSI_EH_DONE;
+ }
+
+ static const struct attribute_group *ufshcd_driver_groups[] = {
+--
+2.39.5
+
--- /dev/null
+From a8d422b16457ecc97ac1d7857e69e1d448522cac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Feb 2025 16:20:47 +0530
+Subject: scsi: ufs: core: Set default runtime/system PM levels before
+ ufshcd_hba_init()
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit fe06b7c07f3fbcce2a2ca6f7b0d543b5699ea00f ]
+
+Commit bb9850704c04 ("scsi: ufs: core: Honor runtime/system PM levels if
+set by host controller drivers") introduced the check for setting default
+PM levels only if the levels are uninitialized by the host controller
+drivers. But it missed the fact that the levels could be initialized to 0
+(UFS_PM_LVL_0) on purpose by the controller drivers. Even though none of
+the drivers are doing so now, the logic should be fixed irrespectively.
+
+So set the default levels unconditionally before calling ufshcd_hba_init()
+API which initializes the controller drivers. It ensures that the
+controller drivers could override the default levels if required.
+
+Fixes: bb9850704c04 ("scsi: ufs: core: Honor runtime/system PM levels if set by host controller drivers")
+Reported-by: Bao D. Nguyen <quic_nguyenb@quicinc.com>
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Link: https://lore.kernel.org/r/20250219105047.49932-1-manivannan.sadhasivam@linaro.org
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index 37b626e128f95..a5bb6ea96460c 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -10494,6 +10494,21 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
+ */
+ spin_lock_init(&hba->clk_gating.lock);
+
++ /*
++ * Set the default power management level for runtime and system PM.
++ * Host controller drivers can override them in their
++ * 'ufs_hba_variant_ops::init' callback.
++ *
++ * Default power saving mode is to keep UFS link in Hibern8 state
++ * and UFS device in sleep state.
++ */
++ hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
++ UFS_SLEEP_PWR_MODE,
++ UIC_LINK_HIBERN8_STATE);
++ hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
++ UFS_SLEEP_PWR_MODE,
++ UIC_LINK_HIBERN8_STATE);
++
+ err = ufshcd_hba_init(hba);
+ if (err)
+ goto out_error;
+@@ -10607,21 +10622,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
+ goto out_disable;
+ }
+
+- /*
+- * Set the default power management level for runtime and system PM if
+- * not set by the host controller drivers.
+- * Default power saving mode is to keep UFS link in Hibern8 state
+- * and UFS device in sleep state.
+- */
+- if (!hba->rpm_lvl)
+- hba->rpm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
+- UFS_SLEEP_PWR_MODE,
+- UIC_LINK_HIBERN8_STATE);
+- if (!hba->spm_lvl)
+- hba->spm_lvl = ufs_get_desired_pm_lvl_for_dev_link_state(
+- UFS_SLEEP_PWR_MODE,
+- UIC_LINK_HIBERN8_STATE);
+-
+ INIT_DELAYED_WORK(&hba->rpm_dev_flush_recheck_work, ufshcd_rpm_dev_flush_recheck_work);
+ INIT_DELAYED_WORK(&hba->ufs_rtc_update_work, ufshcd_rtc_work);
+
+--
+2.39.5
+
--- /dev/null
+rdma-mlx5-fix-the-recovery-flow-of-the-umr-qp.patch
+ib-mlx5-set-and-get-correct-qp_num-for-a-dct-qp.patch
+rdma-mlx5-fix-a-race-for-dmabuf-mr-which-can-lead-to.patch
+rdma-mlx5-fix-a-warn-during-dereg_mr-for-dm-type.patch
+rdma-mana_ib-allocate-page-aligned-doorbell-index.patch
+rdma-hns-fix-mbox-timing-out-by-adding-retry-mechani.patch
+rdma-bnxt_re-add-sanity-checks-on-rdev-validity.patch
+rdma-bnxt_re-allocate-dev_attr-information-dynamical.patch
+rdma-bnxt_re-fix-the-statistics-for-gen-p7-vf.patch
+landlock-fix-non-tcp-sockets-restriction.patch
+scsi-ufs-core-fix-ufshcd_is_ufs_dev_busy-and-ufshcd_.patch
+ovl-fix-uaf-in-ovl_dentry_update_reval-by-moving-dpu.patch
+nfs-o_direct-writes-must-check-and-adjust-the-file-l.patch
+nfs-adjust-delegated-timestamps-for-o_direct-reads-a.patch
+sunrpc-prevent-looping-due-to-rpc_signal_task-races.patch
+nfsv4-fix-a-deadlock-when-recovering-state-on-a-sill.patch
+sunrpc-handle-etimedout-return-from-tlshd.patch
+rdma-mlx5-fix-implicit-odp-hang-on-parent-deregistra.patch
+rdma-mlx5-fix-ah-static-rate-parsing.patch
+scsi-core-clear-driver-private-data-when-retrying-re.patch
+scsi-ufs-core-set-default-runtime-system-pm-levels-b.patch
+rdma-mlx5-fix-bind-qp-error-cleanup-flow.patch
+rdma-bnxt_re-fix-the-page-details-for-the-srq-create.patch
+sunrpc-suppress-warnings-for-unused-procfs-functions.patch
--- /dev/null
+From 4756d0780bc05b8685655e89514225c94d5a2e13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Feb 2025 12:31:57 -0500
+Subject: SUNRPC: Handle -ETIMEDOUT return from tlshd
+
+From: Benjamin Coddington <bcodding@redhat.com>
+
+[ Upstream commit 7a2f6f7687c5f7083a35317cddec5ad9fa491443 ]
+
+If the TLS handshake attempt returns -ETIMEDOUT, we currently translate
+that error into -EACCES. This becomes problematic for cases where the RPC
+layer is attempting to re-connect in paths that don't resonably handle
+-EACCES, for example: writeback. The RPC layer can handle -ETIMEDOUT quite
+well, however - so if the handshake returns this error let's just pass it
+along.
+
+Fixes: 75eb6af7acdf ("SUNRPC: Add a TCP-with-TLS RPC transport class")
+Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/xprtsock.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index c60936d8cef71..6b80b2aaf7639 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -2581,7 +2581,15 @@ static void xs_tls_handshake_done(void *data, int status, key_serial_t peerid)
+ struct sock_xprt *lower_transport =
+ container_of(lower_xprt, struct sock_xprt, xprt);
+
+- lower_transport->xprt_err = status ? -EACCES : 0;
++ switch (status) {
++ case 0:
++ case -EACCES:
++ case -ETIMEDOUT:
++ lower_transport->xprt_err = status;
++ break;
++ default:
++ lower_transport->xprt_err = -EACCES;
++ }
+ complete(&lower_transport->handshake_done);
+ xprt_put(lower_xprt);
+ }
+--
+2.39.5
+
--- /dev/null
+From 73cd5d8700db85dfc73da303d3c91ea267ca5d6c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Feb 2025 15:00:02 -0500
+Subject: SUNRPC: Prevent looping due to rpc_signal_task() races
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 5bbd6e863b15a85221e49b9bdb2d5d8f0bb91f3d ]
+
+If rpc_signal_task() is called while a task is in an rpc_call_done()
+callback function, and the latter calls rpc_restart_call(), the task can
+end up looping due to the RPC_TASK_SIGNALLED flag being set without the
+tk_rpc_status being set.
+Removing the redundant mechanism for signalling the task fixes the
+looping behaviour.
+
+Reported-by: Li Lingfeng <lilingfeng3@huawei.com>
+Fixes: 39494194f93b ("SUNRPC: Fix races with rpc_killall_tasks()")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/sunrpc/sched.h | 3 +--
+ include/trace/events/sunrpc.h | 3 +--
+ net/sunrpc/sched.c | 2 --
+ 3 files changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
+index fec1e8a1570c3..eac57914dcf32 100644
+--- a/include/linux/sunrpc/sched.h
++++ b/include/linux/sunrpc/sched.h
+@@ -158,7 +158,6 @@ enum {
+ RPC_TASK_NEED_XMIT,
+ RPC_TASK_NEED_RECV,
+ RPC_TASK_MSG_PIN_WAIT,
+- RPC_TASK_SIGNALLED,
+ };
+
+ #define rpc_test_and_set_running(t) \
+@@ -171,7 +170,7 @@ enum {
+
+ #define RPC_IS_ACTIVATED(t) test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate)
+
+-#define RPC_SIGNALLED(t) test_bit(RPC_TASK_SIGNALLED, &(t)->tk_runstate)
++#define RPC_SIGNALLED(t) (READ_ONCE(task->tk_rpc_status) == -ERESTARTSYS)
+
+ /*
+ * Task priorities.
+diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
+index b13dc275ef4a7..851841336ee65 100644
+--- a/include/trace/events/sunrpc.h
++++ b/include/trace/events/sunrpc.h
+@@ -360,8 +360,7 @@ TRACE_EVENT(rpc_request,
+ { (1UL << RPC_TASK_ACTIVE), "ACTIVE" }, \
+ { (1UL << RPC_TASK_NEED_XMIT), "NEED_XMIT" }, \
+ { (1UL << RPC_TASK_NEED_RECV), "NEED_RECV" }, \
+- { (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" }, \
+- { (1UL << RPC_TASK_SIGNALLED), "SIGNALLED" })
++ { (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" })
+
+ DECLARE_EVENT_CLASS(rpc_task_running,
+
+diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
+index cef623ea15060..9b45fbdc90cab 100644
+--- a/net/sunrpc/sched.c
++++ b/net/sunrpc/sched.c
+@@ -864,8 +864,6 @@ void rpc_signal_task(struct rpc_task *task)
+ if (!rpc_task_set_rpc_status(task, -ERESTARTSYS))
+ return;
+ trace_rpc_task_signalled(task, task->tk_action);
+- set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate);
+- smp_mb__after_atomic();
+ queue = READ_ONCE(task->tk_waitqueue);
+ if (queue)
+ rpc_wake_up_queued_task(queue, task);
+--
+2.39.5
+
--- /dev/null
+From 86293082c396d5197c32462801c786d9ed5ec012 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Feb 2025 15:52:21 +0100
+Subject: sunrpc: suppress warnings for unused procfs functions
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 1f7a4f98c11fbeb18ed21f3b3a497e90a50ad2e0 ]
+
+There is a warning about unused variables when building with W=1 and no procfs:
+
+net/sunrpc/cache.c:1660:30: error: 'cache_flush_proc_ops' defined but not used [-Werror=unused-const-variable=]
+ 1660 | static const struct proc_ops cache_flush_proc_ops = {
+ | ^~~~~~~~~~~~~~~~~~~~
+net/sunrpc/cache.c:1622:30: error: 'content_proc_ops' defined but not used [-Werror=unused-const-variable=]
+ 1622 | static const struct proc_ops content_proc_ops = {
+ | ^~~~~~~~~~~~~~~~
+net/sunrpc/cache.c:1598:30: error: 'cache_channel_proc_ops' defined but not used [-Werror=unused-const-variable=]
+ 1598 | static const struct proc_ops cache_channel_proc_ops = {
+ | ^~~~~~~~~~~~~~~~~~~~~~
+
+These are used inside of an #ifdef, so replacing that with an
+IS_ENABLED() check lets the compiler see how they are used while
+still dropping them during dead code elimination.
+
+Fixes: dbf847ecb631 ("knfsd: allow cache_register to return error on failure")
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Acked-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/cache.c | 10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
+index 059f6ef1ad189..7fcb0574fc79e 100644
+--- a/net/sunrpc/cache.c
++++ b/net/sunrpc/cache.c
+@@ -1669,12 +1669,14 @@ static void remove_cache_proc_entries(struct cache_detail *cd)
+ }
+ }
+
+-#ifdef CONFIG_PROC_FS
+ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
+ {
+ struct proc_dir_entry *p;
+ struct sunrpc_net *sn;
+
++ if (!IS_ENABLED(CONFIG_PROC_FS))
++ return 0;
++
+ sn = net_generic(net, sunrpc_net_id);
+ cd->procfs = proc_mkdir(cd->name, sn->proc_net_rpc);
+ if (cd->procfs == NULL)
+@@ -1702,12 +1704,6 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
+ remove_cache_proc_entries(cd);
+ return -ENOMEM;
+ }
+-#else /* CONFIG_PROC_FS */
+-static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
+-{
+- return 0;
+-}
+-#endif
+
+ void __init cache_initialize(void)
+ {
+--
+2.39.5
+