Skip to content

Commit 5d580e0

Browse files
authored
Merge pull request #240 from truenas/NAS-139627
NAS-139627 / 26.0.0-BETA.1 / NTB: ntb_transport: Preallocate memory windows
2 parents 68615be + 0852db2 commit 5d580e0

File tree

1 file changed

+43
-7
lines changed

1 file changed

+43
-7
lines changed

drivers/ntb/ntb_transport.c

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

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

@@ -931,8 +931,8 @@ static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw,
931931
xlat_size = round_up(size, xlat_align_size);
932932
buff_size = round_up(size, xlat_align);
933933

934-
/* No need to re-setup */
935-
if (mw->xlat_size == xlat_size)
934+
/* No need to re-setup if size already matches */
935+
if (mw->xlat_size == xlat_size && mw->buff_size == buff_size)
936936
return 0;
937937

938938
if (mw->buff_size)
@@ -1052,8 +1052,11 @@ static void ntb_transport_link_cleanup(struct ntb_transport_ctx *nt)
10521052
if (!nt->link_is_up)
10531053
cancel_delayed_work_sync(&nt->link_work);
10541054

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

10581061
/* The scratchpad registers keep the values if the remote side
10591062
* goes down, blast them now to give them a sane value the next
@@ -1339,6 +1342,34 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt,
13391342
return 0;
13401343
}
13411344

1345+
/*
1346+
* Speculatively pre-allocate memory assuming symmetric config.
1347+
* This grabs contiguous memory early before fragmentation.
1348+
* If peer has different size, we'll reallocate on link-up.
1349+
*/
1350+
static void ntb_preallocate_mws(struct ntb_transport_ctx *nt)
1351+
{
1352+
struct ntb_transport_mw *mw;
1353+
resource_size_t size;
1354+
int i, rc;
1355+
1356+
for (i = 0; i < nt->mw_count; i++) {
1357+
mw = &nt->mw_vec[i];
1358+
size = mw->phys_size;
1359+
1360+
if (max_mw_size && size > max_mw_size)
1361+
size = max_mw_size;
1362+
1363+
rc = ntb_set_mw(nt, i, size);
1364+
if (rc) {
1365+
dev_info(&nt->ndev->pdev->dev,
1366+
"Failed to preallocate MW%d (size %llx): %d\n",
1367+
i, (unsigned long long)size, rc);
1368+
/* Continue - link-up will retry */
1369+
}
1370+
}
1371+
}
1372+
13421373
static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
13431374
{
13441375
struct ntb_transport_ctx *nt;
@@ -1484,6 +1515,9 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
14841515
INIT_WORK(&nt->link_cleanup, ntb_transport_link_cleanup_work);
14851516
nt->link_is_up = false;
14861517

1518+
/* Speculatively pre-allocate MW buffers to avoid fragmentation */
1519+
ntb_preallocate_mws(nt);
1520+
14871521
rc = ntb_set_ctx(ndev, nt, &ntb_transport_ops);
14881522
if (rc)
14891523
goto err2;
@@ -1503,9 +1537,11 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
15031537
err2:
15041538
kfree(nt->qp_vec);
15051539
err1:
1506-
while (i--) {
1540+
for (i = 0; i < mw_count; i++) {
15071541
mw = &nt->mw_vec[i];
1508-
iounmap(mw->vbase);
1542+
ntb_free_mw(nt, i);
1543+
if (mw->vbase)
1544+
iounmap(mw->vbase);
15091545
}
15101546
kfree(nt->mw_vec);
15111547
err:

0 commit comments

Comments
 (0)