From 072de836f53be56a70cecf70b43ae43b7ce17376 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 10:08:36 +0000
Subject: [PATCH] mk-rootfs.sh
---
kernel/drivers/rknpu/rknpu_mem.c | 130 ++++++++++++++++++++++++++++++++++++++----
1 files changed, 116 insertions(+), 14 deletions(-)
diff --git a/kernel/drivers/rknpu/rknpu_mem.c b/kernel/drivers/rknpu/rknpu_mem.c
index a3bf982..5242f15 100644
--- a/kernel/drivers/rknpu/rknpu_mem.c
+++ b/kernel/drivers/rknpu/rknpu_mem.c
@@ -15,7 +15,10 @@
#include "rknpu_ioctl.h"
#include "rknpu_mem.h"
-int rknpu_mem_create_ioctl(struct rknpu_device *rknpu_dev, unsigned long data)
+#ifdef CONFIG_ROCKCHIP_RKNPU_DMA_HEAP
+
+int rknpu_mem_create_ioctl(struct rknpu_device *rknpu_dev, unsigned long data,
+ struct file *file)
{
struct rknpu_mem_create args;
int ret = -EINVAL;
@@ -27,6 +30,7 @@
struct page **pages;
struct page *page;
struct rknpu_mem_object *rknpu_obj = NULL;
+ struct rknpu_session *session = NULL;
int i, fd;
unsigned int length, page_count;
@@ -65,6 +69,8 @@
O_CLOEXEC | O_RDWR, 0x0,
dev_name(rknpu_dev->dev));
if (IS_ERR(dmabuf)) {
+ LOG_ERROR("dmabuf alloc failed, args.size = %llu\n",
+ args.size);
ret = PTR_ERR(dmabuf);
goto err_free_obj;
}
@@ -74,6 +80,7 @@
fd = dma_buf_fd(dmabuf, O_CLOEXEC | O_RDWR);
if (fd < 0) {
+ LOG_ERROR("dmabuf fd get failed\n");
ret = -EFAULT;
goto err_free_dma_buf;
}
@@ -81,12 +88,14 @@
attachment = dma_buf_attach(dmabuf, rknpu_dev->dev);
if (IS_ERR(attachment)) {
+ LOG_ERROR("dma_buf_attach failed\n");
ret = PTR_ERR(attachment);
goto err_free_dma_buf;
}
table = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);
if (IS_ERR(table)) {
+ LOG_ERROR("dma_buf_attach failed\n");
dma_buf_detach(dmabuf, attachment);
ret = PTR_ERR(table);
goto err_free_dma_buf;
@@ -101,8 +110,9 @@
}
page_count = length >> PAGE_SHIFT;
- pages = kmalloc_array(page_count, sizeof(struct page), GFP_KERNEL);
+ pages = vmalloc(page_count * sizeof(struct page));
if (!pages) {
+ LOG_ERROR("alloc pages failed\n");
ret = -ENOMEM;
goto err_detach_dma_buf;
}
@@ -112,6 +122,7 @@
rknpu_obj->kv_addr = vmap(pages, page_count, VM_MAP, PAGE_KERNEL);
if (!rknpu_obj->kv_addr) {
+ LOG_ERROR("vmap pages addr failed\n");
ret = -ENOMEM;
goto err_free_pages;
}
@@ -137,9 +148,22 @@
goto err_unmap_kv_addr;
}
- kfree(pages);
+ vfree(pages);
+ pages = NULL;
dma_buf_unmap_attachment(attachment, table, DMA_BIDIRECTIONAL);
dma_buf_detach(dmabuf, attachment);
+
+ spin_lock(&rknpu_dev->lock);
+
+ session = file->private_data;
+ if (!session) {
+ spin_unlock(&rknpu_dev->lock);
+ ret = -EFAULT;
+ goto err_unmap_kv_addr;
+ }
+ list_add_tail(&rknpu_obj->head, &session->list);
+
+ spin_unlock(&rknpu_dev->lock);
return 0;
@@ -148,7 +172,8 @@
rknpu_obj->kv_addr = NULL;
err_free_pages:
- kfree(pages);
+ vfree(pages);
+ pages = NULL;
err_detach_dma_buf:
dma_buf_unmap_attachment(attachment, table, DMA_BIDIRECTIONAL);
@@ -166,11 +191,12 @@
return ret;
}
-int rknpu_mem_destroy_ioctl(struct rknpu_device *rknpu_dev, unsigned long data)
+int rknpu_mem_destroy_ioctl(struct rknpu_device *rknpu_dev, unsigned long data,
+ struct file *file)
{
- struct rknpu_mem_object *rknpu_obj = NULL;
+ struct rknpu_mem_object *rknpu_obj, *entry, *q;
+ struct rknpu_session *session = NULL;
struct rknpu_mem_destroy args;
- struct dma_buf *dmabuf;
int ret = -EFAULT;
if (unlikely(copy_from_user(&args, (struct rknpu_mem_destroy *)data,
@@ -188,28 +214,91 @@
}
rknpu_obj = (struct rknpu_mem_object *)(uintptr_t)args.obj_addr;
- dmabuf = rknpu_obj->dmabuf;
LOG_DEBUG(
"free args.handle: %d, rknpu_obj: %#llx, rknpu_obj->dma_addr: %#llx\n",
args.handle, (__u64)(uintptr_t)rknpu_obj,
(__u64)rknpu_obj->dma_addr);
- vunmap(rknpu_obj->kv_addr);
- rknpu_obj->kv_addr = NULL;
+ spin_lock(&rknpu_dev->lock);
+ session = file->private_data;
+ if (!session) {
+ spin_unlock(&rknpu_dev->lock);
+ ret = -EFAULT;
+ return ret;
+ }
+ list_for_each_entry_safe(entry, q, &session->list, head) {
+ if (entry == rknpu_obj) {
+ list_del(&entry->head);
+ break;
+ }
+ }
+ spin_unlock(&rknpu_dev->lock);
- if (!rknpu_obj->owner)
- dma_buf_put(dmabuf);
+ if (rknpu_obj == entry) {
+ vunmap(rknpu_obj->kv_addr);
+ rknpu_obj->kv_addr = NULL;
- kfree(rknpu_obj);
+ if (!rknpu_obj->owner)
+ dma_buf_put(rknpu_obj->dmabuf);
+
+ kfree(rknpu_obj);
+ }
return 0;
+}
+
+/*
+ * begin cpu access => for_cpu = true
+ * end cpu access => for_cpu = false
+ */
+static void __maybe_unused rknpu_dma_buf_sync(
+ struct rknpu_device *rknpu_dev, struct rknpu_mem_object *rknpu_obj,
+ u32 offset, u32 length, enum dma_data_direction dir, bool for_cpu)
+{
+ struct device *dev = rknpu_dev->dev;
+ struct sg_table *sgt = rknpu_obj->sgt;
+ struct scatterlist *sg = sgt->sgl;
+ dma_addr_t sg_dma_addr = sg_dma_address(sg);
+ unsigned int len = 0;
+ int i;
+
+ for_each_sgtable_sg(sgt, sg, i) {
+ unsigned int sg_offset, sg_left, size = 0;
+
+ len += sg->length;
+ if (len <= offset) {
+ sg_dma_addr += sg->length;
+ continue;
+ }
+
+ sg_left = len - offset;
+ sg_offset = sg->length - sg_left;
+
+ size = (length < sg_left) ? length : sg_left;
+
+ if (for_cpu)
+ dma_sync_single_range_for_cpu(dev, sg_dma_addr,
+ sg_offset, size, dir);
+ else
+ dma_sync_single_range_for_device(dev, sg_dma_addr,
+ sg_offset, size, dir);
+
+ offset += size;
+ length -= size;
+ sg_dma_addr += sg->length;
+
+ if (length == 0)
+ break;
+ }
}
int rknpu_mem_sync_ioctl(struct rknpu_device *rknpu_dev, unsigned long data)
{
struct rknpu_mem_object *rknpu_obj = NULL;
struct rknpu_mem_sync args;
+#ifdef CONFIG_DMABUF_PARTIAL
struct dma_buf *dmabuf;
+#endif
int ret = -EFAULT;
if (unlikely(copy_from_user(&args, (struct rknpu_mem_sync *)data,
@@ -227,8 +316,18 @@
}
rknpu_obj = (struct rknpu_mem_object *)(uintptr_t)args.obj_addr;
- dmabuf = rknpu_obj->dmabuf;
+#ifndef CONFIG_DMABUF_PARTIAL
+ if (args.flags & RKNPU_MEM_SYNC_TO_DEVICE) {
+ rknpu_dma_buf_sync(rknpu_dev, rknpu_obj, args.offset, args.size,
+ DMA_TO_DEVICE, false);
+ }
+ if (args.flags & RKNPU_MEM_SYNC_FROM_DEVICE) {
+ rknpu_dma_buf_sync(rknpu_dev, rknpu_obj, args.offset, args.size,
+ DMA_FROM_DEVICE, true);
+ }
+#else
+ dmabuf = rknpu_obj->dmabuf;
if (args.flags & RKNPU_MEM_SYNC_TO_DEVICE) {
dmabuf->ops->end_cpu_access_partial(dmabuf, DMA_TO_DEVICE,
args.offset, args.size);
@@ -237,6 +336,9 @@
dmabuf->ops->begin_cpu_access_partial(dmabuf, DMA_FROM_DEVICE,
args.offset, args.size);
}
+#endif
return 0;
}
+
+#endif
--
Gitblit v1.6.2