Skip to content

Commit 53fe2b5

Browse files
authored
Merge pull request #272 from truenas/sync-6.12-with-release-branch
NAS-141072 / 26.04 / Sync 6.12 with release branch
2 parents 8effa3e + b7e2338 commit 53fe2b5

2 files changed

Lines changed: 74 additions & 9 deletions

File tree

drivers/ntb/ntb_transport.c

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ MODULE_VERSION(NTB_TRANSPORT_VER);
7373
MODULE_LICENSE("Dual BSD/GPL");
7474
MODULE_AUTHOR("Intel Corporation");
7575

76-
static unsigned long max_mw_size;
76+
static unsigned long max_mw_size = 256 * 1024 * 1024;
7777
module_param(max_mw_size, ulong, 0644);
7878
MODULE_PARM_DESC(max_mw_size, "Limit size of large memory windows");
7979

@@ -927,8 +927,8 @@ static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw,
927927
xlat_size = round_up(size, xlat_align_size);
928928
buff_size = round_up(size, xlat_align);
929929

930-
/* No need to re-setup */
931-
if (mw->xlat_size == xlat_size)
930+
/* No need to re-setup if size already matches */
931+
if (mw->xlat_size == xlat_size && mw->buff_size == buff_size)
932932
return 0;
933933

934934
if (mw->buff_size)
@@ -1048,8 +1048,11 @@ static void ntb_transport_link_cleanup(struct ntb_transport_ctx *nt)
10481048
if (!nt->link_is_up)
10491049
cancel_delayed_work_sync(&nt->link_work);
10501050

1051-
for (i = 0; i < nt->mw_count; i++)
1052-
ntb_free_mw(nt, i);
1051+
/*
1052+
* Do NOT free MW memory on link down. Memory is retained across
1053+
* link cycles to avoid fragmentation from repeated allocation.
1054+
* Memory is only freed on device removal in ntb_transport_free().
1055+
*/
10531056

10541057
/* The scratchpad registers keep the values if the remote side
10551058
* goes down, blast them now to give them a sane value the next
@@ -1332,6 +1335,34 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt,
13321335
return 0;
13331336
}
13341337

1338+
/*
1339+
* Speculatively pre-allocate memory assuming symmetric config.
1340+
* This grabs contiguous memory early before fragmentation.
1341+
* If peer has different size, we'll reallocate on link-up.
1342+
*/
1343+
static void ntb_preallocate_mws(struct ntb_transport_ctx *nt)
1344+
{
1345+
struct ntb_transport_mw *mw;
1346+
resource_size_t size;
1347+
int i, rc;
1348+
1349+
for (i = 0; i < nt->mw_count; i++) {
1350+
mw = &nt->mw_vec[i];
1351+
size = mw->phys_size;
1352+
1353+
if (max_mw_size && size > max_mw_size)
1354+
size = max_mw_size;
1355+
1356+
rc = ntb_set_mw(nt, i, size);
1357+
if (rc) {
1358+
dev_info(&nt->ndev->pdev->dev,
1359+
"Failed to preallocate MW%d (size %llx): %d\n",
1360+
i, (unsigned long long)size, rc);
1361+
/* Continue - link-up will retry */
1362+
}
1363+
}
1364+
}
1365+
13351366
static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
13361367
{
13371368
struct ntb_transport_ctx *nt;
@@ -1476,6 +1507,9 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
14761507
INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup_work);
14771508
nt->link_is_up = false;
14781509

1510+
/* Speculatively pre-allocate MW buffers to avoid fragmentation */
1511+
ntb_preallocate_mws(nt);
1512+
14791513
rc = ntb_set_ctx(ndev, nt, &ntb_transport_ops);
14801514
if (rc)
14811515
goto err2;
@@ -1495,9 +1529,11 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
14951529
err2:
14961530
kfree(nt->qp_vec);
14971531
err1:
1498-
while (i--) {
1532+
for (i = 0; i < mw_count; i++) {
14991533
mw = &nt->mw_vec[i];
1500-
iounmap(mw->vbase);
1534+
ntb_free_mw(nt, i);
1535+
if (mw->vbase)
1536+
iounmap(mw->vbase);
15011537
}
15021538
kfree(nt->mw_vec);
15031539
err:

fs/nfsd/vfs.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,20 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
188188
nfsd_mountpoint(dentry, exp) == 2) {
189189
/* This is only a mountpoint in some other namespace */
190190
path_put(&path);
191+
#ifdef CONFIG_TRUENAS
192+
/*
193+
* For snapdir entries we set LOOKUP_AUTOMOUNT above, so
194+
* if the path is unchanged the automount was attempted
195+
* and failed (EISDIR from zfsctl_snapshot_mount). This
196+
* can happen transiently when zfs_suspend_fs races with
197+
* the mount helper after the z_teardown_lock deadlock
198+
* fix (see https://github.com/openzfs/zfs/pull/18415).
199+
* Return ESTALE so the client retries via LOOKUP rather
200+
* than caching the ctldir stub as an empty directory.
201+
*/
202+
if (is_snapdir)
203+
err = -ESTALE;
204+
#endif /* CONFIG_TRUENAS */
191205
goto out;
192206
}
193207

@@ -201,8 +215,23 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
201215
* allowed without an explicit export of the new
202216
* directory.
203217
*/
204-
if (err == -ENOENT && !(exp->ex_flags & NFSEXP_V4ROOT))
205-
err = 0;
218+
if (err == -ENOENT && !(exp->ex_flags & NFSEXP_V4ROOT)) {
219+
#ifdef CONFIG_TRUENAS
220+
/*
221+
* For ZFS snapshot entries under a zfs_snapdir
222+
* export, the fallback dentry is an automount
223+
* stub with simple_dir_operations that returns
224+
* empty READDIR (NFS4_OK, zero entries). The
225+
* client caches this silently with no error
226+
* signal to trigger re-resolution. Return ESTALE
227+
* so the client retries via LOOKUP.
228+
*/
229+
if (is_snapdir)
230+
err = -ESTALE;
231+
else
232+
#endif /* CONFIG_TRUENAS */
233+
err = 0;
234+
}
206235
path_put(&path);
207236
goto out;
208237
}

0 commit comments

Comments
 (0)