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
