Skip to content

Commit 1c0844c

Browse files
Huan Yangvivekkreddy
authored andcommitted
udmabuf: change folios array from kmalloc to kvmalloc
When PAGE_SIZE 4096, MAX_PAGE_ORDER 10, 64bit machine, page_alloc only support 4MB. If above this, trigger this warn and return NULL. udmabuf can change size limit, if change it to 3072(3GB), and then alloc 3GB udmabuf, will fail create. [ 4080.876581] ------------[ cut here ]------------ [ 4080.876843] WARNING: CPU: 3 PID: 2015 at mm/page_alloc.c:4556 __alloc_pages+0x2c8/0x350 [ 4080.878839] RIP: 0010:__alloc_pages+0x2c8/0x350 [ 4080.879470] Call Trace: [ 4080.879473] <TASK> [ 4080.879473] ? __alloc_pages+0x2c8/0x350 [ 4080.879475] ? __warn.cold+0x8e/0xe8 [ 4080.880647] ? __alloc_pages+0x2c8/0x350 [ 4080.880909] ? report_bug+0xff/0x140 [ 4080.881175] ? handle_bug+0x3c/0x80 [ 4080.881556] ? exc_invalid_op+0x17/0x70 [ 4080.881559] ? asm_exc_invalid_op+0x1a/0x20 [ 4080.882077] ? udmabuf_create+0x131/0x400 Because MAX_PAGE_ORDER, kmalloc can max alloc 4096 * (1 << 10), 4MB memory, each array entry is pointer(8byte), so can save 524288 pages(2GB). Further more, costly order(order 3) may not be guaranteed that it can be applied for, due to fragmentation. This patch change udmabuf array use kvmalloc_array, this can fallback alloc into vmalloc, which can guarantee allocation for any size and does not affect the performance of kmalloc allocations. Signed-off-by: Huan Yang <link@vivo.com> Acked-by: Christian König <christian.koenig@amd.com> Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240918025238.2957823-3-link@vivo.com
1 parent f0bbcc2 commit 1c0844c

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

drivers/dma-buf/udmabuf.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map)
109109

110110
dma_resv_assert_held(buf->resv);
111111

112-
pages = kmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
112+
pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL);
113113
if (!pages)
114114
return -ENOMEM;
115115

116116
for (pg = 0; pg < ubuf->pagecount; pg++)
117117
pages[pg] = &ubuf->folios[pg]->page;
118118

119119
vaddr = vm_map_ram(pages, ubuf->pagecount, -1);
120-
kfree(pages);
120+
kvfree(pages);
121121
if (!vaddr)
122122
return -EINVAL;
123123

@@ -225,8 +225,8 @@ static void release_udmabuf(struct dma_buf *buf)
225225
put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL);
226226

227227
unpin_all_folios(&ubuf->unpin_list);
228-
kfree(ubuf->offsets);
229-
kfree(ubuf->folios);
228+
kvfree(ubuf->offsets);
229+
kvfree(ubuf->folios);
230230
kfree(ubuf);
231231
}
232232

@@ -351,14 +351,14 @@ static long udmabuf_create(struct miscdevice *device,
351351
if (!ubuf->pagecount)
352352
goto err;
353353

354-
ubuf->folios = kmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios),
355-
GFP_KERNEL);
354+
ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios),
355+
GFP_KERNEL);
356356
if (!ubuf->folios) {
357357
ret = -ENOMEM;
358358
goto err;
359359
}
360-
ubuf->offsets = kcalloc(ubuf->pagecount, sizeof(*ubuf->offsets),
361-
GFP_KERNEL);
360+
ubuf->offsets = kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets),
361+
GFP_KERNEL);
362362
if (!ubuf->offsets) {
363363
ret = -ENOMEM;
364364
goto err;
@@ -372,7 +372,7 @@ static long udmabuf_create(struct miscdevice *device,
372372
goto err;
373373

374374
pgcnt = list[i].size >> PAGE_SHIFT;
375-
folios = kmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
375+
folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
376376
if (!folios) {
377377
ret = -ENOMEM;
378378
goto err;
@@ -382,7 +382,7 @@ static long udmabuf_create(struct miscdevice *device,
382382
ret = memfd_pin_folios(memfd, list[i].offset, end,
383383
folios, pgcnt, &pgoff);
384384
if (ret <= 0) {
385-
kfree(folios);
385+
kvfree(folios);
386386
if (!ret)
387387
ret = -EINVAL;
388388
goto err;
@@ -411,7 +411,7 @@ static long udmabuf_create(struct miscdevice *device,
411411
}
412412
}
413413

414-
kfree(folios);
414+
kvfree(folios);
415415
fput(memfd);
416416
memfd = NULL;
417417
}
@@ -427,8 +427,8 @@ static long udmabuf_create(struct miscdevice *device,
427427
if (memfd)
428428
fput(memfd);
429429
unpin_all_folios(&ubuf->unpin_list);
430-
kfree(ubuf->offsets);
431-
kfree(ubuf->folios);
430+
kvfree(ubuf->offsets);
431+
kvfree(ubuf->folios);
432432
kfree(ubuf);
433433
return ret;
434434
}

0 commit comments

Comments
 (0)