From: Tao Cui <[email protected]>

udmabuf pins the pages of a memfd and hands them out as a dma-buf.  The
data pages keep the accounting of the memfd they were instantiated in,
but the bookkeeping around them does not: the page pointer array and
the pinned_folios array, both sized by the buffer page count, plus the
transient folios array sized by the memfd folio count, are plain
GFP_KERNEL.  A 1GB buffer costs about 4MB of uncharged SUnreclaim
memory, and size_limit_mb defaults to INT_MAX.

Charge the three kvmalloc allocations so the creator pays for the
metadata it induces.  The system heap in the same subsystem already
accounts its buffer allocation; the data pages here stay with the
memfd.

Signed-off-by: Tao Cui <[email protected]>
---
 drivers/dma-buf/udmabuf.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index df6dd0046242..40182c82df6b 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -190,11 +190,12 @@ static void unpin_all_folios(struct udmabuf *ubuf)
 
 static __always_inline int init_udmabuf(struct udmabuf *ubuf, pgoff_t pgcnt)
 {
-       ubuf->pages = kvmalloc_objs(*ubuf->pages, pgcnt);
+       ubuf->pages = kvmalloc_objs(*ubuf->pages, pgcnt, GFP_KERNEL_ACCOUNT);
        if (!ubuf->pages)
                return -ENOMEM;
 
-       ubuf->pinned_folios = kvmalloc_objs(*ubuf->pinned_folios, pgcnt);
+       ubuf->pinned_folios = kvmalloc_objs(*ubuf->pinned_folios, pgcnt,
+                                           GFP_KERNEL_ACCOUNT);
        if (!ubuf->pinned_folios)
                return -ENOMEM;
 
@@ -387,7 +388,7 @@ static long udmabuf_create(struct miscdevice *device,
        if (ret)
                goto err;
 
-       folios = kvmalloc_objs(*folios, max_nr_folios);
+       folios = kvmalloc_objs(*folios, max_nr_folios, GFP_KERNEL_ACCOUNT);
        if (!folios) {
                ret = -ENOMEM;
                goto err;
-- 
2.43.0


Reply via email to