Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nvmet-rdma: use kvcalloc for commands and responses arrays

Replace kcalloc with kvcalloc for allocation of the commands and
responses arrays. Each command structure is 272 bytes and each
response structure is 672 bytes. These arrays typically exceed a
single page, and grow much larger with high queue depths
(e.g., commands >2MB, responses >170KB)

kvcalloc automatically falls back to vmalloc for large or fragmented
allocations, improving reliability. In our case, this memory is not
aimed for DMA operations and could be safely allocated by kvcalloc.
Using virtually contiguous memory helps to avoid allocation failures
and out-of-memory conditions common with kcalloc on large pools.

Signed-off-by: Israel Rukshin <israelr@nvidia.com>
Reviewed-by: Max Gurtovoy <mgurtovoy@nvidia.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>

authored by

Israel Rukshin and committed by
Keith Busch
ce234d83 b645d5a2

+6 -6
+6 -6
drivers/nvme/target/rdma.c
··· 367 367 struct nvmet_rdma_cmd *cmds; 368 368 int ret = -EINVAL, i; 369 369 370 - cmds = kcalloc(nr_cmds, sizeof(struct nvmet_rdma_cmd), GFP_KERNEL); 370 + cmds = kvcalloc(nr_cmds, sizeof(struct nvmet_rdma_cmd), GFP_KERNEL); 371 371 if (!cmds) 372 372 goto out; 373 373 ··· 382 382 out_free: 383 383 while (--i >= 0) 384 384 nvmet_rdma_free_cmd(ndev, cmds + i, admin); 385 - kfree(cmds); 385 + kvfree(cmds); 386 386 out: 387 387 return ERR_PTR(ret); 388 388 } ··· 394 394 395 395 for (i = 0; i < nr_cmds; i++) 396 396 nvmet_rdma_free_cmd(ndev, cmds + i, admin); 397 - kfree(cmds); 397 + kvfree(cmds); 398 398 } 399 399 400 400 static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, ··· 455 455 NUMA_NO_NODE, false, true)) 456 456 goto out; 457 457 458 - queue->rsps = kcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp), 458 + queue->rsps = kvcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp), 459 459 GFP_KERNEL); 460 460 if (!queue->rsps) 461 461 goto out_free_sbitmap; ··· 473 473 out_free: 474 474 while (--i >= 0) 475 475 nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); 476 - kfree(queue->rsps); 476 + kvfree(queue->rsps); 477 477 out_free_sbitmap: 478 478 sbitmap_free(&queue->rsp_tags); 479 479 out: ··· 487 487 488 488 for (i = 0; i < nr_rsps; i++) 489 489 nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); 490 - kfree(queue->rsps); 490 + kvfree(queue->rsps); 491 491 sbitmap_free(&queue->rsp_tags); 492 492 } 493 493