Re: [PATCH v2] misc: sram: Add DMA-BUF Heap exporting of SRAM areas

2023-04-03 Thread kernel test robot
Hi Andrew,

kernel test robot noticed the following build warnings:

[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on char-misc/char-misc-next char-misc/char-misc-linus 
soc/for-next pza/reset/next linus/master v6.3-rc5 next-20230403]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Andrew-Davis/misc-sram-Add-DMA-BUF-Heap-exporting-of-SRAM-areas/20230404-032607
patch link:https://lore.kernel.org/r/20230403192433.26648-1-afd%40ti.com
patch subject: [PATCH v2] misc: sram: Add DMA-BUF Heap exporting of SRAM areas
config: loongarch-allyesconfig 
(https://download.01.org/0day-ci/archive/20230404/202304041144.t5jcogse-...@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/6fcaa3c7cfbc144dd982f9abaa1c5af50dde24a8
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Andrew-Davis/misc-sram-Add-DMA-BUF-Heap-exporting-of-SRAM-areas/20230404-032607
git checkout 6fcaa3c7cfbc144dd982f9abaa1c5af50dde24a8
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=loongarch olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=loongarch SHELL=/bin/bash drivers/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 
| Link: 
https://lore.kernel.org/oe-kbuild-all/202304041144.t5jcogse-...@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/misc/sram-dma-heap.c:161:17: warning: no previous prototype for 
>> 'sram_dma_heap_allocate' [-Wmissing-prototypes]
 161 | struct dma_buf *sram_dma_heap_allocate(struct dma_heap *heap,
 | ^~


vim +/sram_dma_heap_allocate +161 drivers/misc/sram-dma-heap.c

   160  
 > 161  struct dma_buf *sram_dma_heap_allocate(struct dma_heap *heap,
   162 unsigned long len,
   163 unsigned long fd_flags,
   164 unsigned long heap_flags)
   165  {
   166  struct sram_dma_heap *sram_dma_heap = 
dma_heap_get_drvdata(heap);
   167  struct sram_dma_heap_buffer *buffer;
   168  
   169  DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
   170  struct dma_buf *dmabuf;
   171  int ret;
   172  
   173  buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
   174  if (!buffer)
   175  return ERR_PTR(-ENOMEM);
   176  buffer->pool = sram_dma_heap->pool;
   177  INIT_LIST_HEAD(>attachments);
   178  mutex_init(>attachments_lock);
   179  buffer->len = len;
   180  
   181  buffer->vaddr = (void *)gen_pool_alloc(buffer->pool, 
buffer->len);
   182  if (!buffer->vaddr) {
   183  ret = -ENOMEM;
   184  goto free_buffer;
   185  }
   186  
   187  buffer->paddr = gen_pool_virt_to_phys(buffer->pool, (unsigned 
long)buffer->vaddr);
   188  if (buffer->paddr == -1) {
   189  ret = -ENOMEM;
   190  goto free_pool;
   191  }
   192  
   193  /* create the dmabuf */
   194  exp_info.exp_name = dma_heap_get_name(heap);
   195  exp_info.ops = _dma_heap_buf_ops;
   196  exp_info.size = buffer->len;
   197  exp_info.flags = fd_flags;
   198  exp_info.priv = buffer;
   199  dmabuf = dma_buf_export(_info);
   200  if (IS_ERR(dmabuf)) {
   201  ret = PTR_ERR(dmabuf);
   202  goto free_pool;
   203  }
   204  
   205  return dmabuf;
   206  
   207  free_pool:
   208  gen_pool_free(buffer->pool, (unsigned long)buffer->vaddr, 
buffer->len);
   209  free_buffer:
   210  kfree(buffer);
   211  
   212  return ERR_PTR(ret);
   213  }
   214  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests


[PATCH v2] misc: sram: Add DMA-BUF Heap exporting of SRAM areas

2023-04-03 Thread Andrew Davis
This new export type exposes to userspace the SRAM area as a DMA-BUF Heap,
this allows for allocations of DMA-BUFs that can be consumed by various
DMA-BUF supporting devices.

Signed-off-by: Andrew Davis 
---

Changes from v1:
 - Use existing DT flags, if both pool(device usable) and export(userspace
   usable) properties are in the SRAM node then export as a DMA-BUF Heap
 - Rebase on 6.3-rc5

 drivers/misc/Kconfig |   7 +
 drivers/misc/Makefile|   1 +
 drivers/misc/sram-dma-heap.c | 245 +++
 drivers/misc/sram.c  |   6 +
 drivers/misc/sram.h  |  16 +++
 5 files changed, 275 insertions(+)
 create mode 100644 drivers/misc/sram-dma-heap.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 433aa41977852..8b4c111a6493b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -448,6 +448,13 @@ config SRAM
 config SRAM_EXEC
bool
 
+config SRAM_DMA_HEAP
+   bool "Export on-chip SRAM pools using DMA-Heaps"
+   depends on DMABUF_HEAPS && SRAM
+   help
+ This driver allows the export of on-chip SRAM marked as both pool
+ and exportable to userspace using the DMA-Heaps interface.
+
 config DW_XDATA_PCIE
depends on PCI
tristate "Synopsys DesignWare xData PCIe driver"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 56de43943cd51..bbdc64aa8af1a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
 obj-$(CONFIG_LATTICE_ECP3_CONFIG)  += lattice-ecp3-config.o
 obj-$(CONFIG_SRAM) += sram.o
 obj-$(CONFIG_SRAM_EXEC)+= sram-exec.o
+obj-$(CONFIG_SRAM_DMA_HEAP)+= sram-dma-heap.o
 obj-$(CONFIG_GENWQE)   += genwqe/
 obj-$(CONFIG_ECHO) += echo/
 obj-$(CONFIG_CXL_BASE) += cxl/
diff --git a/drivers/misc/sram-dma-heap.c b/drivers/misc/sram-dma-heap.c
new file mode 100644
index 0..c511f4ac1280e
--- /dev/null
+++ b/drivers/misc/sram-dma-heap.c
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SRAM DMA-Heap userspace exporter
+ *
+ * Copyright (C) 2019-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Andrew Davis 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "sram.h"
+
+struct sram_dma_heap {
+   struct dma_heap *heap;
+   struct gen_pool *pool;
+};
+
+struct sram_dma_heap_buffer {
+   struct gen_pool *pool;
+   struct list_head attachments;
+   struct mutex attachments_lock;
+   unsigned long len;
+   void *vaddr;
+   phys_addr_t paddr;
+};
+
+struct dma_heap_attachment {
+   struct device *dev;
+   struct sg_table *table;
+   struct list_head list;
+};
+
+static int dma_heap_attach(struct dma_buf *dmabuf,
+  struct dma_buf_attachment *attachment)
+{
+   struct sram_dma_heap_buffer *buffer = dmabuf->priv;
+   struct dma_heap_attachment *a;
+   struct sg_table *table;
+
+   a = kzalloc(sizeof(*a), GFP_KERNEL);
+   if (!a)
+   return -ENOMEM;
+
+   table = kmalloc(sizeof(*table), GFP_KERNEL);
+   if (!table) {
+   kfree(a);
+   return -ENOMEM;
+   }
+   if (sg_alloc_table(table, 1, GFP_KERNEL)) {
+   kfree(table);
+   kfree(a);
+   return -ENOMEM;
+   }
+   sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(buffer->paddr)), 
buffer->len, 0);
+
+   a->table = table;
+   a->dev = attachment->dev;
+   INIT_LIST_HEAD(>list);
+
+   attachment->priv = a;
+
+   mutex_lock(>attachments_lock);
+   list_add(>list, >attachments);
+   mutex_unlock(>attachments_lock);
+
+   return 0;
+}
+
+static void dma_heap_detatch(struct dma_buf *dmabuf,
+struct dma_buf_attachment *attachment)
+{
+   struct sram_dma_heap_buffer *buffer = dmabuf->priv;
+   struct dma_heap_attachment *a = attachment->priv;
+
+   mutex_lock(>attachments_lock);
+   list_del(>list);
+   mutex_unlock(>attachments_lock);
+
+   sg_free_table(a->table);
+   kfree(a->table);
+   kfree(a);
+}
+
+static struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment 
*attachment,
+enum dma_data_direction direction)
+{
+   struct dma_heap_attachment *a = attachment->priv;
+   struct sg_table *table = a->table;
+
+   /*
+* As this heap is backed by uncached SRAM memory we do not need to
+* perform any sync operations on the buffer before allowing device
+* domain access. For this reason we use SKIP_CPU_SYNC and also do
+* not use or provide begin/end_cpu_access() dma-buf functions.
+*/
+   if (!dma_map_sg_attrs(attachment->dev, table->sgl, table->nents,
+ direction, DMA_ATTR_SKIP_CPU_SYNC))
+