The system dma-buf heap lets userspace allocate buffers from the page
allocator. However, these allocations are not accounted for in memcg,
allowing processes to escape limits that may be configured.

Pass __GFP_ACCOUNT for system heap allocations, based on the
dma_heap.mem_accounting parameter, to use memcg and account for them.

Signed-off-by: Eric Chanudet <[email protected]>
---
 drivers/dma-buf/heaps/system_heap.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/heaps/system_heap.c 
b/drivers/dma-buf/heaps/system_heap.c
index 
4c782fe33fd497a74eb5065797259576f9b651b6..139b50df64ed4c4a6fdd69f25fe48324fbe2c481
 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -52,6 +52,8 @@ static gfp_t order_flags[] = {HIGH_ORDER_GFP, HIGH_ORDER_GFP, 
LOW_ORDER_GFP};
 static const unsigned int orders[] = {8, 4, 0};
 #define NUM_ORDERS ARRAY_SIZE(orders)
 
+extern bool mem_accounting;
+
 static int dup_sg_table(struct sg_table *from, struct sg_table *to)
 {
        struct scatterlist *sg, *new_sg;
@@ -320,14 +322,17 @@ static struct page *alloc_largest_available(unsigned long 
size,
 {
        struct page *page;
        int i;
+       gfp_t flags;
 
        for (i = 0; i < NUM_ORDERS; i++) {
                if (size <  (PAGE_SIZE << orders[i]))
                        continue;
                if (max_order < orders[i])
                        continue;
-
-               page = alloc_pages(order_flags[i], orders[i]);
+               flags = order_flags[i];
+               if (mem_accounting)
+                       flags |= __GFP_ACCOUNT;
+               page = alloc_pages(flags, orders[i]);
                if (!page)
                        continue;
                return page;

-- 
2.52.0

Reply via email to