Hook mem_cgroup_charge_cma() and mem_cgroup_uncharge_cma() into the CMA
alloc/release paths.

In __cma_alloc_frozen(), charge the pages to the current task's cgroup
if the allocation succeeds. Should charging fail (e.g, reaches a limit),
release the pages. Uncharge in __cma_release_frozen().

Signed-off-by: Eric Chanudet <[email protected]>
---
 mm/cma.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/mm/cma.c b/mm/cma.c
index 03f98f6d45a5..03eb3acbd3c7 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -904,6 +904,12 @@ static struct page *__cma_alloc_frozen(struct cma *cma,
                cma_debug_show_areas(cma);
        }
 
+       if (page && mem_cgroup_charge_cma(page, count, cma)) {
+               free_contig_frozen_range(page_to_pfn(page), count);
+               cma_clear_bitmap(cma, &cma->ranges[r], page_to_pfn(page), 
count);
+               page = NULL;
+       }
+
        pr_debug("%s(): returned %p\n", __func__, page);
        trace_cma_alloc_finish(name, page ? page_to_pfn(page) : 0,
                               page, count, align, ret);
@@ -997,6 +1003,7 @@ static void __cma_release_frozen(struct cma *cma, struct 
cma_memrange *cmr,
 
        pr_debug("%s(page %p, count %lu)\n", __func__, (void *)pages, count);
 
+       mem_cgroup_uncharge_cma(pages, count, cma);
        free_contig_frozen_range(pfn, count);
        cma_clear_bitmap(cma, cmr, pfn, count);
        cma_sysfs_account_release_pages(cma, count);

-- 
2.53.0


Reply via email to