From: Sasha Levin Date: Thu, 26 Oct 2023 13:08:30 +0000 (-0400) Subject: Fixes for 6.5 X-Git-Tag: v6.1.61~77 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5bd7b8297de75769dde535318b40e2e3d2633f77;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.5 Signed-off-by: Sasha Levin --- diff --git a/queue-6.5/riscv-fix-set_huge_pte_at-for-napot-mappings-when-a-.patch b/queue-6.5/riscv-fix-set_huge_pte_at-for-napot-mappings-when-a-.patch new file mode 100644 index 00000000000..209c80fdaea --- /dev/null +++ b/queue-6.5/riscv-fix-set_huge_pte_at-for-napot-mappings-when-a-.patch @@ -0,0 +1,72 @@ +From 6b227295b4c6294efce1a5ec1b1a050ebbbb23ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Sep 2023 17:18:46 +0200 +Subject: riscv: fix set_huge_pte_at() for NAPOT mappings when a swap entry is + set + +From: Alexandre Ghiti + +[ Upstream commit 1de195dd0e05d9cba43dec16f83d4ee32af94dd2 ] + +We used to determine the number of page table entries to set for a NAPOT +hugepage by using the pte value which actually fails when the pte to set +is a swap entry. + +So take advantage of a recent fix for arm64 reported in [1] which +introduces the size of the mapping as an argument of set_huge_pte_at(): we +can then use this size to compute the number of page table entries to set +for a NAPOT region. + +Link: https://lkml.kernel.org/r/20230928151846.8229-3-alexghiti@rivosinc.com +Fixes: 82a1a1f3bfb6 ("riscv: mm: support Svnapot in hugetlb page") +Signed-off-by: Alexandre Ghiti +Reported-by: Ryan Roberts +Closes: https://lore.kernel.org/linux-arm-kernel/20230922115804.2043771-1-ryan.roberts@arm.com/ [1] +Reviewed-by: Andrew Jones +Cc: Albert Ou +Cc: Palmer Dabbelt +Cc: Paul Walmsley +Cc: Qinglin Pan +Cc: Conor Dooley +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + arch/riscv/mm/hugetlbpage.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c +index 96225a8533ad8..e92e89461c3bc 100644 +--- a/arch/riscv/mm/hugetlbpage.c ++++ b/arch/riscv/mm/hugetlbpage.c +@@ -182,15 +182,22 @@ void set_huge_pte_at(struct mm_struct *mm, + pte_t *ptep, + pte_t pte) + { ++ unsigned long hugepage_shift; + int i, pte_num; + +- if (!pte_napot(pte)) { +- set_pte_at(mm, addr, ptep, pte); +- return; +- } ++ if (sz >= PGDIR_SIZE) ++ hugepage_shift = PGDIR_SHIFT; ++ else if (sz >= P4D_SIZE) ++ hugepage_shift = P4D_SHIFT; ++ else if (sz >= PUD_SIZE) ++ hugepage_shift = PUD_SHIFT; ++ else if (sz >= PMD_SIZE) ++ hugepage_shift = PMD_SHIFT; ++ else ++ hugepage_shift = PAGE_SHIFT; + +- pte_num = napot_pte_num(napot_cont_order(pte)); +- for (i = 0; i < pte_num; i++, ptep++, addr += PAGE_SIZE) ++ pte_num = sz >> hugepage_shift; ++ for (i = 0; i < pte_num; i++, ptep++, addr += (1 << hugepage_shift)) + set_pte_at(mm, addr, ptep, pte); + } + +-- +2.42.0 + diff --git a/queue-6.5/series b/queue-6.5/series new file mode 100644 index 00000000000..7a6ffa9ec21 --- /dev/null +++ b/queue-6.5/series @@ -0,0 +1,8 @@ +riscv-fix-set_huge_pte_at-for-napot-mappings-when-a-.patch +vdpa-mlx5-fix-firmware-error-on-creation-of-1k-vqs.patch +smb3-allow-controlling-length-of-time-directory-entr.patch +smb3-allow-controlling-maximum-number-of-cached-dire.patch +smb3-do-not-start-laundromat-thread-when-dir-leases.patch +smb-client-do-not-start-laundromat-thread-on-nohandl.patch +smb-client-make-laundromat-a-delayed-worker.patch +smb-client-prevent-new-fids-from-being-removed-by-la.patch diff --git a/queue-6.5/smb-client-do-not-start-laundromat-thread-on-nohandl.patch b/queue-6.5/smb-client-do-not-start-laundromat-thread-on-nohandl.patch new file mode 100644 index 00000000000..0da477978de --- /dev/null +++ b/queue-6.5/smb-client-do-not-start-laundromat-thread-on-nohandl.patch @@ -0,0 +1,72 @@ +From ca3c9d2d3d14b0cb9e15baf154bb5025b555c4be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 17:28:38 -0300 +Subject: smb: client: do not start laundromat thread on nohandlecache + +From: Paulo Alcantara + +[ Upstream commit 3b8bb3171571f92eda863e5f78b063604c61f72a ] + +Honor 'nohandlecache' mount option by not starting laundromat thread +even when SMB server supports directory leases. Do not waste system +resources by having laundromat thread running with no directory +caching at all. + +Fixes: 2da338ff752a ("smb3: do not start laundromat thread when dir leases disabled") +Signed-off-by: Paulo Alcantara (SUSE) +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/connect.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index e70203d07d5d1..bd33661dcb57f 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -2474,8 +2474,9 @@ cifs_put_tcon(struct cifs_tcon *tcon) + static struct cifs_tcon * + cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) + { +- int rc, xid; + struct cifs_tcon *tcon; ++ bool nohandlecache; ++ int rc, xid; + + tcon = cifs_find_tcon(ses, ctx); + if (tcon) { +@@ -2493,14 +2494,17 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) + goto out_fail; + } + +- if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) +- tcon = tcon_info_alloc(true); ++ if (ses->server->dialect >= SMB20_PROT_ID && ++ (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING)) ++ nohandlecache = ctx->nohandlecache; + else +- tcon = tcon_info_alloc(false); ++ nohandlecache = true; ++ tcon = tcon_info_alloc(!nohandlecache); + if (tcon == NULL) { + rc = -ENOMEM; + goto out_fail; + } ++ tcon->nohandlecache = nohandlecache; + + if (ctx->snapshot_time) { + if (ses->server->vals->protocol_id == 0) { +@@ -2662,10 +2666,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) + tcon->nocase = ctx->nocase; + tcon->broken_sparse_sup = ctx->no_sparse; + tcon->max_cached_dirs = ctx->max_cached_dirs; +- if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) +- tcon->nohandlecache = ctx->nohandlecache; +- else +- tcon->nohandlecache = true; + tcon->nodelete = ctx->nodelete; + tcon->local_lease = ctx->local_lease; + INIT_LIST_HEAD(&tcon->pending_opens); +-- +2.42.0 + diff --git a/queue-6.5/smb-client-make-laundromat-a-delayed-worker.patch b/queue-6.5/smb-client-make-laundromat-a-delayed-worker.patch new file mode 100644 index 00000000000..b3f86cd684e --- /dev/null +++ b/queue-6.5/smb-client-make-laundromat-a-delayed-worker.patch @@ -0,0 +1,175 @@ +From d292c9229a94395ae7ac80ac76a168fe41fbe7c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Oct 2023 16:04:25 -0300 +Subject: smb: client: make laundromat a delayed worker + +From: Paulo Alcantara + +[ Upstream commit e95f3f74465072c2545d8e65a3c3a96e37129cf8 ] + +By having laundromat kthread processing cached directories on every +second turned out to be overkill, especially when having multiple SMB +mounts. + +Relax it by using a delayed worker instead that gets scheduled on +every @dir_cache_timeout (default=30) seconds per tcon. + +This also fixes the 1s delay when tearing down tcon. + +Signed-off-by: Paulo Alcantara (SUSE) +Reviewed-by: Shyam Prasad N +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cached_dir.c | 89 +++++++++++++++----------------------- + fs/smb/client/cached_dir.h | 2 +- + 2 files changed, 36 insertions(+), 55 deletions(-) + +diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c +index e2be8aedb26e3..a9e5d3b7e9a05 100644 +--- a/fs/smb/client/cached_dir.c ++++ b/fs/smb/client/cached_dir.c +@@ -15,6 +15,7 @@ + static struct cached_fid *init_cached_dir(const char *path); + static void free_cached_dir(struct cached_fid *cfid); + static void smb2_close_cached_fid(struct kref *ref); ++static void cfids_laundromat_worker(struct work_struct *work); + + static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids, + const char *path, +@@ -572,53 +573,46 @@ static void free_cached_dir(struct cached_fid *cfid) + kfree(cfid); + } + +-static int +-cifs_cfids_laundromat_thread(void *p) ++static void cfids_laundromat_worker(struct work_struct *work) + { +- struct cached_fids *cfids = p; ++ struct cached_fids *cfids; + struct cached_fid *cfid, *q; +- struct list_head entry; ++ LIST_HEAD(entry); + +- while (!kthread_should_stop()) { +- ssleep(1); +- INIT_LIST_HEAD(&entry); +- if (kthread_should_stop()) +- return 0; +- spin_lock(&cfids->cfid_list_lock); +- list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { +- if (time_after(jiffies, cfid->time + HZ * dir_cache_timeout)) { +- list_del(&cfid->entry); +- list_add(&cfid->entry, &entry); +- cfids->num_entries--; +- } ++ cfids = container_of(work, struct cached_fids, laundromat_work.work); ++ ++ spin_lock(&cfids->cfid_list_lock); ++ list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { ++ if (time_after(jiffies, cfid->time + HZ * dir_cache_timeout)) { ++ list_move(&cfid->entry, &entry); ++ cfids->num_entries--; + } +- spin_unlock(&cfids->cfid_list_lock); ++ } ++ spin_unlock(&cfids->cfid_list_lock); + +- list_for_each_entry_safe(cfid, q, &entry, entry) { +- cfid->on_list = false; +- list_del(&cfid->entry); ++ list_for_each_entry_safe(cfid, q, &entry, entry) { ++ cfid->on_list = false; ++ list_del(&cfid->entry); ++ /* ++ * Cancel and wait for the work to finish in case we are racing ++ * with it. ++ */ ++ cancel_work_sync(&cfid->lease_break); ++ if (cfid->has_lease) { + /* +- * Cancel, and wait for the work to finish in +- * case we are racing with it. ++ * Our lease has not yet been cancelled from the server ++ * so we need to drop the reference. + */ +- cancel_work_sync(&cfid->lease_break); +- if (cfid->has_lease) { +- /* +- * We lease has not yet been cancelled from +- * the server so we need to drop the reference. +- */ +- spin_lock(&cfids->cfid_list_lock); +- cfid->has_lease = false; +- spin_unlock(&cfids->cfid_list_lock); +- kref_put(&cfid->refcount, smb2_close_cached_fid); +- } ++ spin_lock(&cfids->cfid_list_lock); ++ cfid->has_lease = false; ++ spin_unlock(&cfids->cfid_list_lock); ++ kref_put(&cfid->refcount, smb2_close_cached_fid); + } + } +- +- return 0; ++ queue_delayed_work(cifsiod_wq, &cfids->laundromat_work, ++ dir_cache_timeout * HZ); + } + +- + struct cached_fids *init_cached_dirs(void) + { + struct cached_fids *cfids; +@@ -629,19 +623,10 @@ struct cached_fids *init_cached_dirs(void) + spin_lock_init(&cfids->cfid_list_lock); + INIT_LIST_HEAD(&cfids->entries); + +- /* +- * since we're in a cifs function already, we know that +- * this will succeed. No need for try_module_get(). +- */ +- __module_get(THIS_MODULE); +- cfids->laundromat = kthread_run(cifs_cfids_laundromat_thread, +- cfids, "cifsd-cfid-laundromat"); +- if (IS_ERR(cfids->laundromat)) { +- cifs_dbg(VFS, "Failed to start cfids laundromat thread.\n"); +- kfree(cfids); +- module_put(THIS_MODULE); +- return NULL; +- } ++ INIT_DELAYED_WORK(&cfids->laundromat_work, cfids_laundromat_worker); ++ queue_delayed_work(cifsiod_wq, &cfids->laundromat_work, ++ dir_cache_timeout * HZ); ++ + return cfids; + } + +@@ -657,11 +642,7 @@ void free_cached_dirs(struct cached_fids *cfids) + if (cfids == NULL) + return; + +- if (cfids->laundromat) { +- kthread_stop(cfids->laundromat); +- cfids->laundromat = NULL; +- module_put(THIS_MODULE); +- } ++ cancel_delayed_work_sync(&cfids->laundromat_work); + + spin_lock(&cfids->cfid_list_lock); + list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { +diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h +index a82ff2cea789c..81ba0fd5cc16d 100644 +--- a/fs/smb/client/cached_dir.h ++++ b/fs/smb/client/cached_dir.h +@@ -57,7 +57,7 @@ struct cached_fids { + spinlock_t cfid_list_lock; + int num_entries; + struct list_head entries; +- struct task_struct *laundromat; ++ struct delayed_work laundromat_work; + }; + + extern struct cached_fids *init_cached_dirs(void); +-- +2.42.0 + diff --git a/queue-6.5/smb-client-prevent-new-fids-from-being-removed-by-la.patch b/queue-6.5/smb-client-prevent-new-fids-from-being-removed-by-la.patch new file mode 100644 index 00000000000..8448219658e --- /dev/null +++ b/queue-6.5/smb-client-prevent-new-fids-from-being-removed-by-la.patch @@ -0,0 +1,147 @@ +From edbe618f8c8c2164bfc78c34bec098e34de2c2ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 17:37:40 -0300 +Subject: smb: client: prevent new fids from being removed by laundromat + +From: Paulo Alcantara + +[ Upstream commit 81ba10959970d15c388bf29866b01b62f387e6a3 ] + +Check if @cfid->time is set in laundromat so we guarantee that only +fully cached fids will be selected for removal. While we're at it, +add missing locks to protect access of @cfid fields in order to avoid +races with open_cached_dir() and cfids_laundromat_worker(), +respectively. + +Signed-off-by: Paulo Alcantara (SUSE) +Reviewed-by: Shyam Prasad N +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cached_dir.c | 56 ++++++++++++++++++++++++-------------- + 1 file changed, 35 insertions(+), 21 deletions(-) + +diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c +index a9e5d3b7e9a05..fe1bf5b6e0cb3 100644 +--- a/fs/smb/client/cached_dir.c ++++ b/fs/smb/client/cached_dir.c +@@ -170,15 +170,18 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, + return -ENOENT; + } + /* +- * At this point we either have a lease already and we can just +- * return it. If not we are guaranteed to be the only thread accessing +- * this cfid. ++ * Return cached fid if it has a lease. Otherwise, it is either a new ++ * entry or laundromat worker removed it from @cfids->entries. Caller ++ * will put last reference if the latter. + */ ++ spin_lock(&cfids->cfid_list_lock); + if (cfid->has_lease) { ++ spin_unlock(&cfids->cfid_list_lock); + *ret_cfid = cfid; + kfree(utf16_path); + return 0; + } ++ spin_unlock(&cfids->cfid_list_lock); + + /* + * Skip any prefix paths in @path as lookup_positive_unlocked() ends up +@@ -295,9 +298,11 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, + goto oshr_free; + } + } ++ spin_lock(&cfids->cfid_list_lock); + cfid->dentry = dentry; + cfid->time = jiffies; + cfid->has_lease = true; ++ spin_unlock(&cfids->cfid_list_lock); + + oshr_free: + kfree(utf16_path); +@@ -306,24 +311,28 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, + free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); + free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); + spin_lock(&cfids->cfid_list_lock); +- if (rc && !cfid->has_lease) { +- if (cfid->on_list) { +- list_del(&cfid->entry); +- cfid->on_list = false; +- cfids->num_entries--; ++ if (!cfid->has_lease) { ++ if (rc) { ++ if (cfid->on_list) { ++ list_del(&cfid->entry); ++ cfid->on_list = false; ++ cfids->num_entries--; ++ } ++ rc = -ENOENT; ++ } else { ++ /* ++ * We are guaranteed to have two references at this ++ * point. One for the caller and one for a potential ++ * lease. Release the Lease-ref so that the directory ++ * will be closed when the caller closes the cached ++ * handle. ++ */ ++ spin_unlock(&cfids->cfid_list_lock); ++ kref_put(&cfid->refcount, smb2_close_cached_fid); ++ goto out; + } +- rc = -ENOENT; + } + spin_unlock(&cfids->cfid_list_lock); +- if (!rc && !cfid->has_lease) { +- /* +- * We are guaranteed to have two references at this point. +- * One for the caller and one for a potential lease. +- * Release the Lease-ref so that the directory will be closed +- * when the caller closes the cached handle. +- */ +- kref_put(&cfid->refcount, smb2_close_cached_fid); +- } + if (rc) { + if (cfid->is_open) + SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid, +@@ -331,7 +340,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, + free_cached_dir(cfid); + cfid = NULL; + } +- ++out: + if (rc == 0) { + *ret_cfid = cfid; + atomic_inc(&tcon->num_remote_opens); +@@ -583,15 +592,18 @@ static void cfids_laundromat_worker(struct work_struct *work) + + spin_lock(&cfids->cfid_list_lock); + list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { +- if (time_after(jiffies, cfid->time + HZ * dir_cache_timeout)) { ++ if (cfid->time && ++ time_after(jiffies, cfid->time + HZ * dir_cache_timeout)) { ++ cfid->on_list = false; + list_move(&cfid->entry, &entry); + cfids->num_entries--; ++ /* To prevent race with smb2_cached_lease_break() */ ++ kref_get(&cfid->refcount); + } + } + spin_unlock(&cfids->cfid_list_lock); + + list_for_each_entry_safe(cfid, q, &entry, entry) { +- cfid->on_list = false; + list_del(&cfid->entry); + /* + * Cancel and wait for the work to finish in case we are racing +@@ -608,6 +620,8 @@ static void cfids_laundromat_worker(struct work_struct *work) + spin_unlock(&cfids->cfid_list_lock); + kref_put(&cfid->refcount, smb2_close_cached_fid); + } ++ /* Drop the extra reference opened above */ ++ kref_put(&cfid->refcount, smb2_close_cached_fid); + } + queue_delayed_work(cifsiod_wq, &cfids->laundromat_work, + dir_cache_timeout * HZ); +-- +2.42.0 + diff --git a/queue-6.5/smb3-allow-controlling-length-of-time-directory-entr.patch b/queue-6.5/smb3-allow-controlling-length-of-time-directory-entr.patch new file mode 100644 index 00000000000..07053b5eed7 --- /dev/null +++ b/queue-6.5/smb3-allow-controlling-length-of-time-directory-entr.patch @@ -0,0 +1,97 @@ +From 7030e469508b99343ca8b27f4acf8aeeb7d51fc6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 30 Aug 2023 22:48:41 -0500 +Subject: smb3: allow controlling length of time directory entries are cached + with dir leases + +From: Steve French + +[ Upstream commit 238b351d0935df568ecb3dc5aef25971778f0f7c ] + +Currently with directory leases we cache directory contents for a fixed period +of time (default 30 seconds) but for many workloads this is too short. Allow +configuring the maximum amount of time directory entries are cached when a +directory lease is held on that directory. Add module load parm "max_dir_cache" + +For example to set the timeout to 10 minutes you would do: + + echo 600 > /sys/module/cifs/parameters/dir_cache_timeout + +or to disable caching directory contents: + + echo 0 > /sys/module/cifs/parameters/dir_cache_timeout + +Reviewed-by: Bharath SM +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cached_dir.c | 4 ++-- + fs/smb/client/cifsfs.c | 10 ++++++++++ + fs/smb/client/cifsglob.h | 1 + + 3 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c +index 2d5e9a9d5b8be..9d84c4a7bd0ce 100644 +--- a/fs/smb/client/cached_dir.c ++++ b/fs/smb/client/cached_dir.c +@@ -145,7 +145,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, + const char *npath; + + if (tcon == NULL || tcon->cfids == NULL || tcon->nohandlecache || +- is_smb1_server(tcon->ses->server)) ++ is_smb1_server(tcon->ses->server) || (dir_cache_timeout == 0)) + return -EOPNOTSUPP; + + ses = tcon->ses; +@@ -582,7 +582,7 @@ cifs_cfids_laundromat_thread(void *p) + return 0; + spin_lock(&cfids->cfid_list_lock); + list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { +- if (time_after(jiffies, cfid->time + HZ * 30)) { ++ if (time_after(jiffies, cfid->time + HZ * dir_cache_timeout)) { + list_del(&cfid->entry); + list_add(&cfid->entry, &entry); + cfids->num_entries--; +diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c +index a4d8b0ea1c8cb..9a6d7e66408d1 100644 +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -117,6 +117,10 @@ module_param(cifs_max_pending, uint, 0444); + MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server for " + "CIFS/SMB1 dialect (N/A for SMB3) " + "Default: 32767 Range: 2 to 32767."); ++unsigned int dir_cache_timeout = 30; ++module_param(dir_cache_timeout, uint, 0644); ++MODULE_PARM_DESC(dir_cache_timeout, "Number of seconds to cache directory contents for which we have a lease. Default: 30 " ++ "Range: 1 to 65000 seconds, 0 to disable caching dir contents"); + #ifdef CONFIG_CIFS_STATS2 + unsigned int slow_rsp_threshold = 1; + module_param(slow_rsp_threshold, uint, 0644); +@@ -1679,6 +1683,12 @@ init_cifs(void) + CIFS_MAX_REQ); + } + ++ /* Limit max to about 18 hours, and setting to zero disables directory entry caching */ ++ if (dir_cache_timeout > 65000) { ++ dir_cache_timeout = 65000; ++ cifs_dbg(VFS, "dir_cache_timeout set to max of 65000 seconds\n"); ++ } ++ + cifsiod_wq = alloc_workqueue("cifsiod", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); + if (!cifsiod_wq) { + rc = -ENOMEM; +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index 35782a6bede0b..f8eb787ecffab 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -1987,6 +1987,7 @@ extern unsigned int CIFSMaxBufSize; /* max size not including hdr */ + extern unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ + extern unsigned int cifs_min_small; /* min size of small buf pool */ + extern unsigned int cifs_max_pending; /* MAX requests at once to server*/ ++extern unsigned int dir_cache_timeout; /* max time for directory lease caching of dir */ + extern bool disable_legacy_dialects; /* forbid vers=1.0 and vers=2.0 mounts */ + extern atomic_t mid_count; + +-- +2.42.0 + diff --git a/queue-6.5/smb3-allow-controlling-maximum-number-of-cached-dire.patch b/queue-6.5/smb3-allow-controlling-maximum-number-of-cached-dire.patch new file mode 100644 index 00000000000..e53f83f5013 --- /dev/null +++ b/queue-6.5/smb3-allow-controlling-maximum-number-of-cached-dire.patch @@ -0,0 +1,174 @@ +From 2d238af1cd45ff4fdd3b7ef161f41f686bc02756 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 Sep 2023 02:15:14 -0500 +Subject: smb3: allow controlling maximum number of cached directories + +From: Steve French + +[ Upstream commit 6a50d71d0ffff6791737eb502b27f74fb87d0cae ] + +Allow adjusting the maximum number of cached directories per share +(defaults to 16) via mount parm "max_cached_dirs" + +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/cached_dir.c | 7 ++++--- + fs/smb/client/cached_dir.h | 2 +- + fs/smb/client/cifsfs.c | 2 ++ + fs/smb/client/cifsglob.h | 1 + + fs/smb/client/connect.c | 1 + + fs/smb/client/fs_context.c | 11 ++++++++++- + fs/smb/client/fs_context.h | 4 +++- + 7 files changed, 22 insertions(+), 6 deletions(-) + +diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c +index 9d84c4a7bd0ce..b17f067e4ada0 100644 +--- a/fs/smb/client/cached_dir.c ++++ b/fs/smb/client/cached_dir.c +@@ -18,7 +18,8 @@ static void smb2_close_cached_fid(struct kref *ref); + + static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids, + const char *path, +- bool lookup_only) ++ bool lookup_only, ++ __u32 max_cached_dirs) + { + struct cached_fid *cfid; + +@@ -43,7 +44,7 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids, + spin_unlock(&cfids->cfid_list_lock); + return NULL; + } +- if (cfids->num_entries >= MAX_CACHED_FIDS) { ++ if (cfids->num_entries >= max_cached_dirs) { + spin_unlock(&cfids->cfid_list_lock); + return NULL; + } +@@ -162,7 +163,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, + if (!utf16_path) + return -ENOMEM; + +- cfid = find_or_create_cached_dir(cfids, path, lookup_only); ++ cfid = find_or_create_cached_dir(cfids, path, lookup_only, tcon->max_cached_dirs); + if (cfid == NULL) { + kfree(utf16_path); + return -ENOENT; +diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h +index facc9b154d009..a82ff2cea789c 100644 +--- a/fs/smb/client/cached_dir.h ++++ b/fs/smb/client/cached_dir.h +@@ -49,7 +49,7 @@ struct cached_fid { + struct cached_dirents dirents; + }; + +-#define MAX_CACHED_FIDS 16 ++/* default MAX_CACHED_FIDS is 16 */ + struct cached_fids { + /* Must be held when: + * - accessing the cfids->entries list +diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c +index 9a6d7e66408d1..e19df244ea7ea 100644 +--- a/fs/smb/client/cifsfs.c ++++ b/fs/smb/client/cifsfs.c +@@ -699,6 +699,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) + seq_printf(s, ",snapshot=%llu", tcon->snapshot_time); + if (tcon->handle_timeout) + seq_printf(s, ",handletimeout=%u", tcon->handle_timeout); ++ if (tcon->max_cached_dirs != MAX_CACHED_FIDS) ++ seq_printf(s, ",max_cached_dirs=%u", tcon->max_cached_dirs); + + /* + * Display file and directory attribute timeout in seconds. +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index f8eb787ecffab..b4c1c4742f08a 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -1192,6 +1192,7 @@ struct cifs_tcon { + __u32 max_chunks; + __u32 max_bytes_chunk; + __u32 max_bytes_copy; ++ __u32 max_cached_dirs; + #ifdef CONFIG_CIFS_FSCACHE + u64 resource_id; /* server resource id */ + struct fscache_volume *fscache; /* cookie for share */ +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index 352e251c41132..f00d02608ee46 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -2657,6 +2657,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) + tcon->retry = ctx->retry; + tcon->nocase = ctx->nocase; + tcon->broken_sparse_sup = ctx->no_sparse; ++ tcon->max_cached_dirs = ctx->max_cached_dirs; + if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) + tcon->nohandlecache = ctx->nohandlecache; + else +diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c +index f12203c49b802..a3493da12ad1e 100644 +--- a/fs/smb/client/fs_context.c ++++ b/fs/smb/client/fs_context.c +@@ -150,6 +150,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = { + fsparam_u32("closetimeo", Opt_closetimeo), + fsparam_u32("echo_interval", Opt_echo_interval), + fsparam_u32("max_credits", Opt_max_credits), ++ fsparam_u32("max_cached_dirs", Opt_max_cached_dirs), + fsparam_u32("handletimeout", Opt_handletimeout), + fsparam_u64("snapshot", Opt_snapshot), + fsparam_u32("max_channels", Opt_max_channels), +@@ -1165,6 +1166,14 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, + if (result.uint_32 > 1) + ctx->multichannel = true; + break; ++ case Opt_max_cached_dirs: ++ if (result.uint_32 < 1) { ++ cifs_errorf(fc, "%s: Invalid max_cached_dirs, needs to be 1 or more\n", ++ __func__); ++ goto cifs_parse_mount_err; ++ } ++ ctx->max_cached_dirs = result.uint_32; ++ break; + case Opt_handletimeout: + ctx->handle_timeout = result.uint_32; + if (ctx->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) { +@@ -1593,7 +1602,7 @@ int smb3_init_fs_context(struct fs_context *fc) + ctx->acregmax = CIFS_DEF_ACTIMEO; + ctx->acdirmax = CIFS_DEF_ACTIMEO; + ctx->closetimeo = SMB3_DEF_DCLOSETIMEO; +- ++ ctx->max_cached_dirs = MAX_CACHED_FIDS; + /* Most clients set timeout to 0, allows server to use its default */ + ctx->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */ + +diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h +index f4eaf85589022..9d8d34af02114 100644 +--- a/fs/smb/client/fs_context.h ++++ b/fs/smb/client/fs_context.h +@@ -128,6 +128,7 @@ enum cifs_param { + Opt_closetimeo, + Opt_echo_interval, + Opt_max_credits, ++ Opt_max_cached_dirs, + Opt_snapshot, + Opt_max_channels, + Opt_handletimeout, +@@ -261,6 +262,7 @@ struct smb3_fs_context { + __u32 handle_timeout; /* persistent and durable handle timeout in ms */ + unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ + unsigned int max_channels; ++ unsigned int max_cached_dirs; + __u16 compression; /* compression algorithm 0xFFFF default 0=disabled */ + bool rootfs:1; /* if it's a SMB root file system */ + bool witness:1; /* use witness protocol */ +@@ -287,7 +289,7 @@ extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb); + */ + #define SMB3_MAX_DCLOSETIMEO (1 << 30) + #define SMB3_DEF_DCLOSETIMEO (1 * HZ) /* even 1 sec enough to help eg open/write/close/open/read */ +- ++#define MAX_CACHED_FIDS 16 + extern char *cifs_sanitize_prepath(char *prepath, gfp_t gfp); + + #endif +-- +2.42.0 + diff --git a/queue-6.5/smb3-do-not-start-laundromat-thread-when-dir-leases.patch b/queue-6.5/smb3-do-not-start-laundromat-thread-when-dir-leases.patch new file mode 100644 index 00000000000..a7df203555d --- /dev/null +++ b/queue-6.5/smb3-do-not-start-laundromat-thread-when-dir-leases.patch @@ -0,0 +1,149 @@ +From 5637d1cdb5ebb083288d4cd3955bc7e64a94e1b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Sep 2023 11:35:53 -0500 +Subject: smb3: do not start laundromat thread when dir leases disabled + +From: Steve French + +When no directory lease support, or for IPC shares where directories +can not be opened, do not start an unneeded laundromat thread for +that mount (it wastes resources). + +Fixes: d14de8067e3f ("cifs: Add a laundromat thread for cached directories") +Reviewed-by: Paulo Alcantara (SUSE) +Acked-by: Tom Talpey +Signed-off-by: Steve French +(cherry picked from commit 2da338ff752a2789470d733111a5241f30026675) +--- + fs/smb/client/cached_dir.c | 6 ++++++ + fs/smb/client/cifsglob.h | 2 +- + fs/smb/client/cifsproto.h | 2 +- + fs/smb/client/connect.c | 8 ++++++-- + fs/smb/client/misc.c | 14 +++++++++----- + fs/smb/client/smb2pdu.c | 2 +- + 6 files changed, 24 insertions(+), 10 deletions(-) + +diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c +index b17f067e4ada0..e2be8aedb26e3 100644 +--- a/fs/smb/client/cached_dir.c ++++ b/fs/smb/client/cached_dir.c +@@ -452,6 +452,9 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon) + struct cached_fid *cfid, *q; + LIST_HEAD(entry); + ++ if (cfids == NULL) ++ return; ++ + spin_lock(&cfids->cfid_list_lock); + list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { + list_move(&cfid->entry, &entry); +@@ -651,6 +654,9 @@ void free_cached_dirs(struct cached_fids *cfids) + struct cached_fid *cfid, *q; + LIST_HEAD(entry); + ++ if (cfids == NULL) ++ return; ++ + if (cfids->laundromat) { + kthread_stop(cfids->laundromat); + cfids->laundromat = NULL; +diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h +index b4c1c4742f08a..ac68fed5ad28a 100644 +--- a/fs/smb/client/cifsglob.h ++++ b/fs/smb/client/cifsglob.h +@@ -1914,7 +1914,7 @@ require use of the stronger protocol */ + * cifsInodeInfo->lock_sem cifsInodeInfo->llist cifs_init_once + * ->can_cache_brlcks + * cifsInodeInfo->deferred_lock cifsInodeInfo->deferred_closes cifsInodeInfo_alloc +- * cached_fid->fid_mutex cifs_tcon->crfid tconInfoAlloc ++ * cached_fid->fid_mutex cifs_tcon->crfid tcon_info_alloc + * cifsFileInfo->fh_mutex cifsFileInfo cifs_new_fileinfo + * cifsFileInfo->file_info_lock cifsFileInfo->count cifs_new_fileinfo + * ->invalidHandle initiate_cifs_search +diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h +index 1d71d658e1679..bd0a1505719a4 100644 +--- a/fs/smb/client/cifsproto.h ++++ b/fs/smb/client/cifsproto.h +@@ -513,7 +513,7 @@ extern int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses); + + extern struct cifs_ses *sesInfoAlloc(void); + extern void sesInfoFree(struct cifs_ses *); +-extern struct cifs_tcon *tconInfoAlloc(void); ++extern struct cifs_tcon *tcon_info_alloc(bool dir_leases_enabled); + extern void tconInfoFree(struct cifs_tcon *); + + extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server, +diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c +index f00d02608ee46..e70203d07d5d1 100644 +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -1882,7 +1882,8 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx) + } + } + +- tcon = tconInfoAlloc(); ++ /* no need to setup directory caching on IPC share, so pass in false */ ++ tcon = tcon_info_alloc(false); + if (tcon == NULL) + return -ENOMEM; + +@@ -2492,7 +2493,10 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) + goto out_fail; + } + +- tcon = tconInfoAlloc(); ++ if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) ++ tcon = tcon_info_alloc(true); ++ else ++ tcon = tcon_info_alloc(false); + if (tcon == NULL) { + rc = -ENOMEM; + goto out_fail; +diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c +index d7e85d9a26553..249fac8be5a51 100644 +--- a/fs/smb/client/misc.c ++++ b/fs/smb/client/misc.c +@@ -113,18 +113,22 @@ sesInfoFree(struct cifs_ses *buf_to_free) + } + + struct cifs_tcon * +-tconInfoAlloc(void) ++tcon_info_alloc(bool dir_leases_enabled) + { + struct cifs_tcon *ret_buf; + + ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL); + if (!ret_buf) + return NULL; +- ret_buf->cfids = init_cached_dirs(); +- if (!ret_buf->cfids) { +- kfree(ret_buf); +- return NULL; ++ ++ if (dir_leases_enabled == true) { ++ ret_buf->cfids = init_cached_dirs(); ++ if (!ret_buf->cfids) { ++ kfree(ret_buf); ++ return NULL; ++ } + } ++ /* else ret_buf->cfids is already set to NULL above */ + + atomic_inc(&tconInfoAllocCount); + ret_buf->status = TID_NEW; +diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c +index 9c7e46b7e7c7a..c22cc72223814 100644 +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -3871,7 +3871,7 @@ void smb2_reconnect_server(struct work_struct *work) + goto done; + + /* allocate a dummy tcon struct used for reconnect */ +- tcon = tconInfoAlloc(); ++ tcon = tcon_info_alloc(false); + if (!tcon) { + resched = true; + list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) { +-- +2.42.0 + diff --git a/queue-6.5/vdpa-mlx5-fix-firmware-error-on-creation-of-1k-vqs.patch b/queue-6.5/vdpa-mlx5-fix-firmware-error-on-creation-of-1k-vqs.patch new file mode 100644 index 00000000000..cbd3c5aa702 --- /dev/null +++ b/queue-6.5/vdpa-mlx5-fix-firmware-error-on-creation-of-1k-vqs.patch @@ -0,0 +1,166 @@ +From 444ef753f11a7e076aa2fa7e9144ad7331141b7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 31 Aug 2023 18:50:56 +0300 +Subject: vdpa/mlx5: Fix firmware error on creation of 1k VQs + +From: Dragos Tatulea + +[ Upstream commit abb0dcf9938c93f765abf8cb45567cadef0af6b2 ] + +A firmware error is triggered when configuring a 9k MTU on the PF after +switching to switchdev mode and then using a vdpa device with larger +(1k) rings: +mlx5_cmd_out_err: CREATE_GENERAL_OBJECT(0xa00) op_mod(0xd) failed, status bad resource(0x5), syndrome (0xf6db90), err(-22) + +This is due to the fact that the hw VQ size parameters are computed +based on the umem_1/2/3_buffer_param_a/b capabilities and all +device capabilities are read only when the driver is moved to switchdev mode. + +The problematic configuration flow looks like this: +1) Create VF +2) Unbind VF +3) Switch PF to switchdev mode. +4) Bind VF +5) Set PF MTU to 9k +6) create vDPA device +7) Start VM with vDPA device and 1K queue size + +Note that setting the MTU before step 3) doesn't trigger this issue. + +This patch reads the forementioned umem parameters at the latest point +possible before the VQs of the device are created. + +v2: +- Allocate output with kmalloc to reduce stack frame size. +- Removed stable from cc. + +Fixes: 1a86b377aa21 ("vdpa/mlx5: Add VDPA driver for supported mlx5 devices") +Signed-off-by: Dragos Tatulea +Message-Id: <20230831155702.1080754-1-dtatulea@nvidia.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/vdpa/mlx5/net/mlx5_vnet.c | 63 ++++++++++++++++++++++++++----- + drivers/vdpa/mlx5/net/mlx5_vnet.h | 9 +++++ + 2 files changed, 63 insertions(+), 9 deletions(-) + +diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c +index 37be945a02308..a01d27b7af1b5 100644 +--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c ++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c +@@ -625,30 +625,70 @@ static void cq_destroy(struct mlx5_vdpa_net *ndev, u16 idx) + mlx5_db_free(ndev->mvdev.mdev, &vcq->db); + } + ++static int read_umem_params(struct mlx5_vdpa_net *ndev) ++{ ++ u32 in[MLX5_ST_SZ_DW(query_hca_cap_in)] = {}; ++ u16 opmod = (MLX5_CAP_VDPA_EMULATION << 1) | (HCA_CAP_OPMOD_GET_CUR & 0x01); ++ struct mlx5_core_dev *mdev = ndev->mvdev.mdev; ++ int out_size; ++ void *caps; ++ void *out; ++ int err; ++ ++ out_size = MLX5_ST_SZ_BYTES(query_hca_cap_out); ++ out = kzalloc(out_size, GFP_KERNEL); ++ if (!out) ++ return -ENOMEM; ++ ++ MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP); ++ MLX5_SET(query_hca_cap_in, in, op_mod, opmod); ++ err = mlx5_cmd_exec_inout(mdev, query_hca_cap, in, out); ++ if (err) { ++ mlx5_vdpa_warn(&ndev->mvdev, ++ "Failed reading vdpa umem capabilities with err %d\n", err); ++ goto out; ++ } ++ ++ caps = MLX5_ADDR_OF(query_hca_cap_out, out, capability); ++ ++ ndev->umem_1_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, umem_1_buffer_param_a); ++ ndev->umem_1_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, umem_1_buffer_param_b); ++ ++ ndev->umem_2_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, umem_2_buffer_param_a); ++ ndev->umem_2_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, umem_2_buffer_param_b); ++ ++ ndev->umem_3_buffer_param_a = MLX5_GET(virtio_emulation_cap, caps, umem_3_buffer_param_a); ++ ndev->umem_3_buffer_param_b = MLX5_GET(virtio_emulation_cap, caps, umem_3_buffer_param_b); ++ ++out: ++ kfree(out); ++ return 0; ++} ++ + static void set_umem_size(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue *mvq, int num, + struct mlx5_vdpa_umem **umemp) + { +- struct mlx5_core_dev *mdev = ndev->mvdev.mdev; +- int p_a; +- int p_b; ++ u32 p_a; ++ u32 p_b; + + switch (num) { + case 1: +- p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_a); +- p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_1_buffer_param_b); ++ p_a = ndev->umem_1_buffer_param_a; ++ p_b = ndev->umem_1_buffer_param_b; + *umemp = &mvq->umem1; + break; + case 2: +- p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_a); +- p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_2_buffer_param_b); ++ p_a = ndev->umem_2_buffer_param_a; ++ p_b = ndev->umem_2_buffer_param_b; + *umemp = &mvq->umem2; + break; + case 3: +- p_a = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_a); +- p_b = MLX5_CAP_DEV_VDPA_EMULATION(mdev, umem_3_buffer_param_b); ++ p_a = ndev->umem_3_buffer_param_a; ++ p_b = ndev->umem_3_buffer_param_b; + *umemp = &mvq->umem3; + break; + } ++ + (*umemp)->size = p_a * mvq->num_ent + p_b; + } + +@@ -2679,6 +2719,11 @@ static int setup_driver(struct mlx5_vdpa_dev *mvdev) + goto out; + } + mlx5_vdpa_add_debugfs(ndev); ++ ++ err = read_umem_params(ndev); ++ if (err) ++ goto err_setup; ++ + err = setup_virtqueues(mvdev); + if (err) { + mlx5_vdpa_warn(mvdev, "setup_virtqueues\n"); +diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.h b/drivers/vdpa/mlx5/net/mlx5_vnet.h +index 36c44d9fdd166..65ebbba206621 100644 +--- a/drivers/vdpa/mlx5/net/mlx5_vnet.h ++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.h +@@ -65,6 +65,15 @@ struct mlx5_vdpa_net { + struct hlist_head macvlan_hash[MLX5V_MACVLAN_SIZE]; + struct mlx5_vdpa_irq_pool irqp; + struct dentry *debugfs; ++ ++ u32 umem_1_buffer_param_a; ++ u32 umem_1_buffer_param_b; ++ ++ u32 umem_2_buffer_param_a; ++ u32 umem_2_buffer_param_b; ++ ++ u32 umem_3_buffer_param_a; ++ u32 umem_3_buffer_param_b; + }; + + struct mlx5_vdpa_counter { +-- +2.42.0 +