The dmem cgroup allows to track any DMA memory allocation made by the
userspace. Let's charge our allocations in videobuf2 to enable proper
memory tracking.

Signed-off-by: Maxime Ripard <mrip...@kernel.org>
---
 drivers/media/common/videobuf2/videobuf2-dma-contig.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c 
b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index 
a13ec569c82f6da2d977222b94af32e74c6c6c82..48384e18030812f4f89f1c225c38def2ac6aa3ca
 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -8,10 +8,11 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation.
  */
 
+#include <linux/cgroup_dmem.h>
 #include <linux/dma-buf.h>
 #include <linux/module.h>
 #include <linux/refcount.h>
 #include <linux/scatterlist.h>
 #include <linux/sched.h>
@@ -40,10 +41,14 @@ struct vb2_dc_buf {
        struct sg_table                 *sgt_base;
 
        /* DMABUF related */
        struct dma_buf_attachment       *db_attach;
 
+#ifdef CONFIG_CGROUP_DMEM
+       struct dmem_cgroup_pool_state   *cgroup_pool_state;
+#endif
+
        struct vb2_buffer               *vb;
        bool                            non_coherent_mem;
 };
 
 /*********************************************/
@@ -169,10 +174,14 @@ static void vb2_dc_put(void *buf_priv)
        struct vb2_dc_buf *buf = buf_priv;
 
        if (!refcount_dec_and_test(&buf->refcount))
                return;
 
+#ifdef CONFIG_CGROUP_DMEM
+       dmem_cgroup_uncharge(buf->cgroup_pool_state, buf->size);
+#endif
+
        if (buf->non_coherent_mem) {
                if (buf->vaddr)
                        dma_vunmap_noncontiguous(buf->dev, buf->vaddr);
                dma_free_noncontiguous(buf->dev, buf->size,
                                       buf->dma_sgt, buf->dma_dir);
@@ -230,10 +239,11 @@ static int vb2_dc_alloc_non_coherent(struct vb2_dc_buf 
*buf)
 
 static void *vb2_dc_alloc(struct vb2_buffer *vb,
                          struct device *dev,
                          unsigned long size)
 {
+       struct dmem_cgroup_pool_state *pool;
        struct vb2_dc_buf *buf;
        int ret;
 
        if (WARN_ON(!dev))
                return ERR_PTR(-EINVAL);
@@ -249,25 +259,34 @@ static void *vb2_dc_alloc(struct vb2_buffer *vb,
 
        buf->size = size;
        /* Prevent the device from being released while the buffer is used */
        buf->dev = get_device(dev);
 
+       ret = dmem_cgroup_try_charge(dma_get_dmem_cgroup_region(dev), size, 
&pool, NULL);
+       if (ret)
+               return ret;
+
        if (buf->non_coherent_mem)
                ret = vb2_dc_alloc_non_coherent(buf);
        else
                ret = vb2_dc_alloc_coherent(buf);
 
        if (ret) {
                dev_err(dev, "dma alloc of size %lu failed\n", size);
+               dmem_cgroup_uncharge(pool, size);
                kfree(buf);
                return ERR_PTR(-ENOMEM);
        }
 
        buf->handler.refcount = &buf->refcount;
        buf->handler.put = vb2_dc_put;
        buf->handler.arg = buf;
 
+#ifdef CONFIG_CGROUP_DMEM
+       buf->cgroup_pool_state = pool;
+#endif
+
        refcount_set(&buf->refcount, 1);
 
        return buf;
 }
 

-- 
2.48.1

Reply via email to