Skip to content

Commit cea0e28

Browse files
Hakon-BuggeNipaLocal
authored andcommitted
RDMA/mlx5: Brute force GFP_NOIO
In mlx5_ib_init(), we call memalloc_noio_{save,restore} in a parenthetic fashion when enabled by the module parameter force_noio. This in order to conditionally enable mlx5_ib to work aligned with I/O devices. Any work queued later on work-queues created during module initialization will inherit the PF_MEMALLOC_{NOIO,NOFS} flag(s), due to commit ("workqueue: Inherit NOIO and NOFS alloc flags"). We do this in order to enable ULPs using the RDMA stack and the mlx5_ib driver to be used as a network block I/O device. This to support a filesystem on top of a raw block device which uses said ULP(s) and the RDMA stack as the network transport layer. Under intense memory pressure, we get memory reclaims. Assume the filesystem reclaims memory, goes to the raw block device, which calls into the ULP in question, which calls the RDMA stack. Now, if regular GFP_KERNEL allocations in ULP or the RDMA stack require reclaims to be fulfilled, we end up in a circular dependency. We break this circular dependency by: 1. Force all allocations in the ULP and the relevant RDMA stack to use GFP_NOIO, by means of a parenthetic use of memalloc_noio_{save,restore} on all relevant entry points. 2. Make sure work-queues inherits current->flags wrt. PF_MEMALLOC_{NOIO,NOFS}, such that work executed on the work-queue inherits the same flag(s). Signed-off-by: Håkon Bugge <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent 87420d7 commit cea0e28

File tree

1 file changed

+18
-4
lines changed
  • drivers/infiniband/hw/mlx5

1 file changed

+18
-4
lines changed

drivers/infiniband/hw/mlx5/main.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ MODULE_AUTHOR("Eli Cohen <[email protected]>");
5656
MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) IB driver");
5757
MODULE_LICENSE("Dual BSD/GPL");
5858

59+
static bool mlx5_ib_force_noio;
60+
module_param_named(force_noio, mlx5_ib_force_noio, bool, 0444);
61+
MODULE_PARM_DESC(force_noio, "Force the use of GFP_NOIO (Y/N)");
62+
5963
struct mlx5_ib_event_work {
6064
struct work_struct work;
6165
union {
@@ -4489,16 +4493,23 @@ static struct auxiliary_driver mlx5r_driver = {
44894493

44904494
static int __init mlx5_ib_init(void)
44914495
{
4496+
unsigned int noio_flags;
44924497
int ret;
44934498

4499+
if (mlx5_ib_force_noio)
4500+
noio_flags = memalloc_noio_save();
4501+
44944502
xlt_emergency_page = (void *)__get_free_page(GFP_KERNEL);
4495-
if (!xlt_emergency_page)
4496-
return -ENOMEM;
4503+
if (!xlt_emergency_page) {
4504+
ret = -ENOMEM;
4505+
goto out;
4506+
}
44974507

44984508
mlx5_ib_event_wq = alloc_ordered_workqueue("mlx5_ib_event_wq", 0);
44994509
if (!mlx5_ib_event_wq) {
45004510
free_page((unsigned long)xlt_emergency_page);
4501-
return -ENOMEM;
4511+
ret = -ENOMEM;
4512+
goto out;
45024513
}
45034514

45044515
ret = mlx5_ib_qp_event_init();
@@ -4515,7 +4526,7 @@ static int __init mlx5_ib_init(void)
45154526
ret = auxiliary_driver_register(&mlx5r_driver);
45164527
if (ret)
45174528
goto drv_err;
4518-
return 0;
4529+
goto out;
45194530

45204531
drv_err:
45214532
auxiliary_driver_unregister(&mlx5r_mp_driver);
@@ -4526,6 +4537,9 @@ static int __init mlx5_ib_init(void)
45264537
qp_event_err:
45274538
destroy_workqueue(mlx5_ib_event_wq);
45284539
free_page((unsigned long)xlt_emergency_page);
4540+
out:
4541+
if (mlx5_ib_force_noio)
4542+
memalloc_noio_restore(noio_flags);
45294543
return ret;
45304544
}
45314545

0 commit comments

Comments
 (0)