Skip to content

Commit 164fd9e

Browse files
Huan Yangvivekkreddy
authored andcommitted
udmabuf: udmabuf_create pin folio codestyle cleanup
This patch aim to simplify the memfd folio pin during the udmabuf create. No functional changes. This patch create a udmabuf_pin_folios function, in this, do the memfd pin folio and then record each pinned folio, offset. This patch simplify the pinned folio record, iter by each pinned folio, and then record each offset in it. Compare to iter by pgcnt, more readable. Suggested-by: Vivek Kasireddy <vivek.kasireddy@intel.com> Signed-off-by: Huan Yang <link@vivo.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-5-link@vivo.com
1 parent 18d7de8 commit 164fd9e

File tree

1 file changed

+76
-61
lines changed

1 file changed

+76
-61
lines changed

drivers/dma-buf/udmabuf.c

Lines changed: 76 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,6 @@ static int check_memfd_seals(struct file *memfd)
291291
{
292292
int seals;
293293

294-
if (!memfd)
295-
return -EBADFD;
296-
297294
if (!shmem_file(memfd) && !is_file_hugepages(memfd))
298295
return -EBADFD;
299296

@@ -328,17 +325,68 @@ static int export_udmabuf(struct udmabuf *ubuf,
328325
return dma_buf_fd(buf, flags);
329326
}
330327

328+
static long udmabuf_pin_folios(struct udmabuf *ubuf, struct file *memfd,
329+
loff_t start, loff_t size)
330+
{
331+
pgoff_t pgoff, pgcnt, upgcnt = ubuf->pagecount;
332+
struct folio **folios = NULL;
333+
u32 cur_folio, cur_pgcnt;
334+
long nr_folios;
335+
long ret = 0;
336+
loff_t end;
337+
338+
pgcnt = size >> PAGE_SHIFT;
339+
folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
340+
if (!folios)
341+
return -ENOMEM;
342+
343+
end = start + (pgcnt << PAGE_SHIFT) - 1;
344+
nr_folios = memfd_pin_folios(memfd, start, end, folios, pgcnt, &pgoff);
345+
if (nr_folios <= 0) {
346+
ret = nr_folios ? nr_folios : -EINVAL;
347+
goto end;
348+
}
349+
350+
cur_pgcnt = 0;
351+
for (cur_folio = 0; cur_folio < nr_folios; ++cur_folio) {
352+
pgoff_t subpgoff = pgoff;
353+
size_t fsize = folio_size(folios[cur_folio]);
354+
355+
ret = add_to_unpin_list(&ubuf->unpin_list, folios[cur_folio]);
356+
if (ret < 0)
357+
goto end;
358+
359+
for (; subpgoff < fsize; subpgoff += PAGE_SIZE) {
360+
ubuf->folios[upgcnt] = folios[cur_folio];
361+
ubuf->offsets[upgcnt] = subpgoff;
362+
++upgcnt;
363+
364+
if (++cur_pgcnt >= pgcnt)
365+
goto end;
366+
}
367+
368+
/**
369+
* In a given range, only the first subpage of the first folio
370+
* has an offset, that is returned by memfd_pin_folios().
371+
* The first subpages of other folios (in the range) have an
372+
* offset of 0.
373+
*/
374+
pgoff = 0;
375+
}
376+
end:
377+
ubuf->pagecount = upgcnt;
378+
kvfree(folios);
379+
return ret;
380+
}
381+
331382
static long udmabuf_create(struct miscdevice *device,
332383
struct udmabuf_create_list *head,
333384
struct udmabuf_create_item *list)
334385
{
335-
pgoff_t pgoff, pgcnt, pglimit, pgbuf = 0;
336-
long nr_folios, ret = -EINVAL;
337-
struct file *memfd = NULL;
338-
struct folio **folios;
386+
pgoff_t pgcnt = 0, pglimit;
339387
struct udmabuf *ubuf;
340-
u32 i, j, k, flags;
341-
loff_t end;
388+
long ret = -EINVAL;
389+
u32 i, flags;
342390

343391
ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL);
344392
if (!ubuf)
@@ -347,81 +395,50 @@ static long udmabuf_create(struct miscdevice *device,
347395
INIT_LIST_HEAD(&ubuf->unpin_list);
348396
pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT;
349397
for (i = 0; i < head->count; i++) {
350-
if (!IS_ALIGNED(list[i].offset, PAGE_SIZE))
398+
if (!PAGE_ALIGNED(list[i].offset))
351399
goto err;
352-
if (!IS_ALIGNED(list[i].size, PAGE_SIZE))
400+
if (!PAGE_ALIGNED(list[i].size))
353401
goto err;
354-
ubuf->pagecount += list[i].size >> PAGE_SHIFT;
355-
if (ubuf->pagecount > pglimit)
402+
403+
pgcnt += list[i].size >> PAGE_SHIFT;
404+
if (pgcnt > pglimit)
356405
goto err;
357406
}
358407

359-
if (!ubuf->pagecount)
408+
if (!pgcnt)
360409
goto err;
361410

362-
ubuf->folios = kvmalloc_array(ubuf->pagecount, sizeof(*ubuf->folios),
363-
GFP_KERNEL);
411+
ubuf->folios = kvmalloc_array(pgcnt, sizeof(*ubuf->folios), GFP_KERNEL);
364412
if (!ubuf->folios) {
365413
ret = -ENOMEM;
366414
goto err;
367415
}
368-
ubuf->offsets = kvcalloc(ubuf->pagecount, sizeof(*ubuf->offsets),
369-
GFP_KERNEL);
416+
417+
ubuf->offsets = kvcalloc(pgcnt, sizeof(*ubuf->offsets), GFP_KERNEL);
370418
if (!ubuf->offsets) {
371419
ret = -ENOMEM;
372420
goto err;
373421
}
374422

375-
pgbuf = 0;
376423
for (i = 0; i < head->count; i++) {
377-
memfd = fget(list[i].memfd);
378-
ret = check_memfd_seals(memfd);
379-
if (ret < 0)
380-
goto err;
424+
struct file *memfd = fget(list[i].memfd);
381425

382-
pgcnt = list[i].size >> PAGE_SHIFT;
383-
folios = kvmalloc_array(pgcnt, sizeof(*folios), GFP_KERNEL);
384-
if (!folios) {
385-
ret = -ENOMEM;
426+
if (!memfd) {
427+
ret = -EBADFD;
386428
goto err;
387429
}
388430

389-
end = list[i].offset + (pgcnt << PAGE_SHIFT) - 1;
390-
ret = memfd_pin_folios(memfd, list[i].offset, end,
391-
folios, pgcnt, &pgoff);
392-
if (ret <= 0) {
393-
kvfree(folios);
394-
if (!ret)
395-
ret = -EINVAL;
431+
ret = check_memfd_seals(memfd);
432+
if (ret < 0) {
433+
fput(memfd);
396434
goto err;
397435
}
398436

399-
nr_folios = ret;
400-
pgoff >>= PAGE_SHIFT;
401-
for (j = 0, k = 0; j < pgcnt; j++) {
402-
ubuf->folios[pgbuf] = folios[k];
403-
ubuf->offsets[pgbuf] = pgoff << PAGE_SHIFT;
404-
405-
if (j == 0 || ubuf->folios[pgbuf-1] != folios[k]) {
406-
ret = add_to_unpin_list(&ubuf->unpin_list,
407-
folios[k]);
408-
if (ret < 0) {
409-
kfree(folios);
410-
goto err;
411-
}
412-
}
413-
414-
pgbuf++;
415-
if (++pgoff == folio_nr_pages(folios[k])) {
416-
pgoff = 0;
417-
if (++k == nr_folios)
418-
break;
419-
}
420-
}
421-
422-
kvfree(folios);
437+
ret = udmabuf_pin_folios(ubuf, memfd, list[i].offset,
438+
list[i].size);
423439
fput(memfd);
424-
memfd = NULL;
440+
if (ret)
441+
goto err;
425442
}
426443

427444
flags = head->flags & UDMABUF_FLAGS_CLOEXEC ? O_CLOEXEC : 0;
@@ -432,8 +449,6 @@ static long udmabuf_create(struct miscdevice *device,
432449
return ret;
433450

434451
err:
435-
if (memfd)
436-
fput(memfd);
437452
unpin_all_folios(&ubuf->unpin_list);
438453
kvfree(ubuf->offsets);
439454
kvfree(ubuf->folios);

0 commit comments

Comments
 (0)