[RFC 5/6] dmabuf: system_heap: implement dma-buf op for GPU cgroup charge transfer

From: Hridya Valsaraju
Date: Fri Jan 14 2022 - 20:08:54 EST


The DMA-BUF op can be invoked when a process that allocated a buffer
relinquishes its ownership and passes it over to another process.

Signed-off-by: Hridya Valsaraju <hridya@xxxxxxxxxx>
---
drivers/dma-buf/heaps/system_heap.c | 43 +++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)

diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index adfdc8c576f2..70f5b98f1157 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -307,6 +307,48 @@ static void system_heap_dma_buf_release(struct dma_buf *dmabuf)
kfree(buffer);
}

+#ifdef CONFIG_CGROUP_GPU
+static int system_heap_dma_buf_charge(struct dma_buf *dmabuf, struct gpucg *gpucg)
+{
+ struct gpucg *current_gpucg;
+ struct gpucg_device *gpucg_dev;
+ struct system_heap_buffer *buffer = dmabuf->priv;
+ size_t len = buffer->len;
+ int ret = 0;
+
+ /*
+ * Check that the process requesting the transfer is the same as the one
+ * to whom the buffer is currently charged to.
+ */
+ current_gpucg = gpucg_get(current);
+ if (current_gpucg != buffer->gpucg)
+ ret = -EPERM;
+
+ gpucg_put(current_gpucg);
+ if (ret)
+ return ret;
+
+ gpucg_dev = dma_heap_get_gpucg_dev(buffer->heap);
+
+ ret = gpucg_try_charge(gpucg, gpucg_dev, len);
+ if (ret)
+ return ret;
+
+ /* uncharge the buffer from the cgroup its currently charged to. */
+ gpucg_uncharge(buffer->gpucg, gpucg_dev, buffer->len);
+ gpucg_put(buffer->gpucg);
+
+ buffer->gpucg = gpucg;
+
+ return 0;
+}
+#else
+static int system_heap_dma_buf_charge(struct dma_buf *dmabuf, struct gpucg *gpucg)
+{
+ return 0;
+}
+#endif
+
static const struct dma_buf_ops system_heap_buf_ops = {
.attach = system_heap_attach,
.detach = system_heap_detach,
@@ -318,6 +360,7 @@ static const struct dma_buf_ops system_heap_buf_ops = {
.vmap = system_heap_vmap,
.vunmap = system_heap_vunmap,
.release = system_heap_dma_buf_release,
+ .charge_to_cgroup = system_heap_dma_buf_charge,
};

static struct page *alloc_largest_available(unsigned long size,
--
2.34.1.703.g22d0c6ccf7-goog