2017-11-30 16:52:08

by Loic Pallardy

[permalink] [raw]
Subject: [PATCH v2 00/16] remoteproc: add fixed memory region support

The aim of the series is to implement carveout memory management as
discussed during OpenAMP weekly call and defined in proposed document [1]

This first series focus only on adding support of the different types of
carveout memories (dynamic, fixed, platform driver depend...).
64bit resource table will be addressed in a next series.

[1]: http://openamp.github.io/docs/mca/coprocessor-memory-definition-v6.pdf

---
Changes since V1:
- Minor corrections on first 7 patches (error management)
- Add "memory device" support on the top of first 7 patches.
Goal is to answer use case reported during OpenAMP weekly discussion:
- "Be able to specify memory region for vring and buffer allocation, even
if no specific request defined in firmware resource table."
Patches offer the capability to create a "memory device" associated to a
carveout with a dedicated DMA memory pool. Different resource handlers are
modified to look-up for specific carveout by name. If match found and associated
"memory device" present, device is used instead of rproc platform device for
allocation.

Loic Pallardy (16):
remoteproc: add rproc_va_to_pa function
remoteproc: add release ops in rproc_mem_entry struct
remoteproc: introduce rproc_add_carveout function
remoteproc: introduce rproc_find_carveout_by_da
remoteproc: modify rproc_handle_carveout to support preallocated
region
remoteproc: modify vring allocation to support preallocated region
remoteproc: st: add reserved memory support
remoteproc: add name in rproc_mem_entry struct
remoteproc: add memory device management support
remoteproc: add memory device registering in rproc_add_carveout
remoteproc: introduce rproc_find_carveout_by_name function
remoteproc: look-up memory-device for vring allocation
remoteproc: look-up memory-device for virtio device allocation
remoteproc: look-up pre-registered carveout by name for carveout
allocation
remoteproc: st: associate memory device to memory regions
rpmsg: virtio: allocate buffer from parent

drivers/remoteproc/remoteproc_core.c | 408 +++++++++++++++++++++++++++++--
drivers/remoteproc/remoteproc_debugfs.c | 1 +
drivers/remoteproc/remoteproc_internal.h | 7 +
drivers/remoteproc/remoteproc_virtio.c | 2 +-
drivers/remoteproc/st_remoteproc.c | 44 +++-
drivers/rpmsg/virtio_rpmsg_bus.c | 2 +-
include/linux/remoteproc.h | 14 +-
7 files changed, 441 insertions(+), 37 deletions(-)

--
1.9.1


From 1585507485765458557@xxx Thu Nov 30 16:02:47 +0000 2017
X-GM-THRID: 1585142010203838290
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread


2017-11-30 16:50:41

by Loic Pallardy

[permalink] [raw]
Subject: [PATCH v2 09/16] remoteproc: add memory device management support

This patch add functions to create and delete some
remoteproc sub-devices with dedicated dma coherent region.

These "memory devices" are identified by their name and
will be used for carveout, vring, buffers allocation
in specific memory region.

Signed-off-by: Loic Pallardy <[email protected]>
---
drivers/remoteproc/remoteproc_core.c | 134 ++++++++++++++++++++++++++++++++---
1 file changed, 123 insertions(+), 11 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index cc53247..76d54bf 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -69,6 +69,127 @@ static const char *rproc_crash_to_string(enum rproc_crash_type type)
return "unknown";
}

+static phys_addr_t rproc_va_to_pa(void *cpu_addr)
+{
+ if (is_vmalloc_addr(cpu_addr)) {
+ return page_to_phys(vmalloc_to_page(cpu_addr)) +
+ offset_in_page(cpu_addr);
+ }
+
+ WARN_ON(!virt_addr_valid(cpu_addr));
+ return virt_to_phys(cpu_addr);
+}
+
+struct rproc_memdev {
+ struct device dev;
+ struct rproc *rproc;
+ struct rproc_mem_entry *mem;
+};
+
+#define to_memdevice(d) container_of(d, struct rproc_memdev, dev)
+
+/**
+ * rproc_memdev_release() - release the existence of a memdevice
+ *
+ * @dev: the subdevice's dev
+ */
+static void rproc_memdev_release(struct device *dev)
+{
+ struct rproc_memdev *memd = to_memdevice(dev);
+
+ kfree(memd);
+}
+
+/**
+ * rproc_memdev_add() - add a memory-device on remote processor
+ *
+ * @rproc: the parent remote processor
+ * @mem: memory resource entry allow to define the dma coherent memory of memory-device
+ *
+ * This function add a memory-device child on rproc parent. This memory-device allow
+ * to define a new dma coherent memory area. When the rproc would alloc a
+ * dma coherent memory it's find the memory-device that match with physical memory
+ * asked (if there is no children that match, the rproc is the default device)
+ *
+ * Returns the memory-device handle on success, and error on failure.
+ */
+static struct rproc_memdev *rproc_memdev_add(struct rproc *rproc,
+ struct rproc_mem_entry *mem)
+{
+ struct rproc_memdev *memd;
+ int ret;
+
+ if (!mem || strlen(mem->name) == 0) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ memd = kzalloc(sizeof(*memd), GFP_KERNEL);
+ if (!memd) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ memd->rproc = rproc;
+ memd->mem = mem;
+ memd->dev.parent = rproc->dev.parent;
+ memd->dev.release = rproc_memdev_release;
+ dev_set_name(&memd->dev, "%s#%s", dev_name(memd->dev.parent), mem->name);
+ dev_set_drvdata(&memd->dev, memd);
+
+ ret = device_register(&memd->dev);
+ if (ret)
+ goto err_dev;
+
+ ret = dmam_declare_coherent_memory(&memd->dev,
+ rproc_va_to_pa(mem->va), mem->da,
+ mem->len,
+ DMA_MEMORY_EXCLUSIVE);
+ if (ret < 0)
+ goto err_dev;
+
+ return memd;
+
+err_dev:
+ put_device(&memd->dev);
+err:
+ dev_err(&rproc->dev, "unable to register subdev %s, err = %d\n",
+ (mem && strlen(mem->name)) ? mem->name : "unnamed", ret);
+ return ERR_PTR(ret);
+}
+
+/**
+ * rproc_memdev_del() - delete a memory-device of remote processor
+ *
+ * @memdev: rproc memory-device
+ */
+static void rproc_memdev_del(struct rproc_memdev *memdev)
+{
+ if (get_device(&memdev->dev)) {
+ device_unregister(&memdev->dev);
+ put_device(&memdev->dev);
+ }
+}
+
+/**
+ * rproc_memdev_unregister() - unregister memory-device of remote processor
+ *
+ * @dev: rproc memory-device
+ * @data: Not use (just to be compliant with device_for_each_child)
+ *
+ * This function is called by device_for_each_child function when unregister
+ * remote processor.
+ */
+static int rproc_memdev_unregister(struct device *dev, void *data)
+{
+ struct rproc_memdev *memd = to_memdevice(dev);
+ struct rproc *rproc = data;
+
+ if (dev != &rproc->dev)
+ rproc_memdev_del(memd);
+ return 0;
+}
+
/*
* This is the IOMMU fault handler we register with the IOMMU API
* (when relevant; not all remote processors access memory through
@@ -139,17 +260,6 @@ static void rproc_disable_iommu(struct rproc *rproc)
iommu_domain_free(domain);
}

-static phys_addr_t rproc_va_to_pa(void *cpu_addr)
-{
- if (is_vmalloc_addr(cpu_addr)) {
- return page_to_phys(vmalloc_to_page(cpu_addr)) +
- offset_in_page(cpu_addr);
- }
-
- WARN_ON(!virt_addr_valid(cpu_addr));
- return virt_to_phys(cpu_addr);
-}
-
/**
* rproc_da_to_va() - lookup the kernel virtual address for a remoteproc address
* @rproc: handle of a remote processor
@@ -1678,6 +1788,8 @@ int rproc_del(struct rproc *rproc)

rproc_delete_debug_dir(rproc);

+ device_for_each_child(rproc->dev.parent, rproc,
+ rproc_memdev_unregister);
/* the rproc is downref'ed as soon as it's removed from the klist */
mutex_lock(&rproc_list_mutex);
list_del(&rproc->node);
--
1.9.1


From 1585493899247846302@xxx Thu Nov 30 12:26:50 +0000 2017
X-GM-THRID: 1585304142205438742
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread

2017-11-30 16:51:00

by Loic Pallardy

[permalink] [raw]
Subject: [PATCH v2 08/16] remoteproc: add name in rproc_mem_entry struct

Add name field in struc rproc_mem_entry.
This new field will be used to match memory area
requested in resource table with pre-registered carveout.

Signed-off-by: Loic Pallardy <[email protected]>
---
drivers/remoteproc/remoteproc_core.c | 1 +
drivers/remoteproc/remoteproc_debugfs.c | 1 +
include/linux/remoteproc.h | 2 ++
3 files changed, 4 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index bdc99cd..cc53247 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -835,6 +835,7 @@ static int rproc_handle_carveout(struct rproc *rproc,
carveout->da = rsc->da;
carveout->release = rproc_release_carveout;
carveout->priv = (void *)CARVEOUT_RSC_ALLOCATED;
+ strncpy(carveout->name, rsc->name, sizeof(carveout->name));

list_add_tail(&carveout->node, &rproc->carveouts);

diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index a204883..fc0e570 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -260,6 +260,7 @@ static int rproc_carveouts_show(struct seq_file *seq, void *p)

list_for_each_entry(carveout, &rproc->carveouts, node) {
seq_puts(seq, "Carveout memory entry:\n");
+ seq_printf(seq, "\tName: %s\n", carveout->name);
seq_printf(seq, "\tVirtual address: %p\n", carveout->va);
seq_printf(seq, "\tDMA address: %pad\n", &carveout->dma);
seq_printf(seq, "\tDevice address: 0x%x\n", carveout->da);
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 5bd5175..66e6863 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -315,6 +315,7 @@ struct fw_rsc_vdev {
* @da: device address
* @release: release associated memory
* @priv: associated data
+ * @name: associated memory region name (optional)
* @node: list node
*/
struct rproc_mem_entry {
@@ -324,6 +325,7 @@ struct rproc_mem_entry {
u32 da;
int (*release)(struct rproc *rproc, struct rproc_mem_entry *mem);
void *priv;
+ char name[32];
struct list_head node;
};

--
1.9.1


From 1585286600480829043@xxx Tue Nov 28 05:31:55 +0000 2017
X-GM-THRID: 1585267334857466187
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread

2017-11-30 16:49:27

by Loic Pallardy

[permalink] [raw]
Subject: [PATCH v2 14/16] remoteproc: look-up pre-registered carveout by name for carveout allocation

Look-up for a pre-registred carveout having the same
name as requested one.
If match found, pre-registed carevout is used and resource
table updated.

Signed-off-by: Loic Pallardy <[email protected]>
---
drivers/remoteproc/remoteproc_core.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 9c12319..8436185 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -873,7 +873,7 @@ static int rproc_handle_carveout(struct rproc *rproc,
struct fw_rsc_carveout *rsc,
int offset, int avail)
{
- struct rproc_mem_entry *carveout, *mapping;
+ struct rproc_mem_entry *carveout, *mapping, *mem;
struct device *dev = &rproc->dev;
dma_addr_t dma;
phys_addr_t pa;
@@ -899,6 +899,7 @@ static int rproc_handle_carveout(struct rproc *rproc,
return -ENOMEM;

/* Check carveout rsc already part of a registered carveout */
+ /* By device address if any */
if (rsc->da != FW_RSC_ADDR_ANY) {
va = rproc_find_carveout_by_da(rproc, rsc->da, rsc->len);

@@ -933,6 +934,20 @@ static int rproc_handle_carveout(struct rproc *rproc,
}
}

+ /* By name */
+ mem = rproc_find_carveout_by_name(rproc, rsc->name);
+ if (mem) {
+ /*
+ * Update resource table with registered carevout information
+ */
+ rsc->len = mem->len;
+ rsc->da = mem->da;
+ rsc->pa = rproc_va_to_pa(mem->va);
+ /* no need to register as already match one for one */
+ return 0;
+ }
+
+ /* No registered carveout found, allocate a new one */
va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL);
if (!va) {
dev_err(dev->parent,
--
1.9.1


From 1585184917516758964@xxx Mon Nov 27 02:35:42 +0000 2017
X-GM-THRID: 1585184917516758964
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread

2017-11-30 16:51:43

by Loic Pallardy

[permalink] [raw]
Subject: [PATCH v2 03/16] remoteproc: introduce rproc_add_carveout function

This patch introduces a new API to allow platform driver to register
platform specific carveout regions.

Signed-off-by: Loic Pallardy <[email protected]>
---
drivers/remoteproc/remoteproc_core.c | 22 ++++++++++++++++++++++
drivers/remoteproc/remoteproc_internal.h | 7 +++++++
include/linux/remoteproc.h | 2 ++
3 files changed, 31 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index f23daf9..279320a 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -737,6 +737,7 @@ static int rproc_handle_carveout(struct rproc *rproc,
carveout->dma = dma;
carveout->da = rsc->da;
carveout->release = rproc_release_carveout;
+ carveout->priv = (void *)CARVEOUT_RSC_ALLOCATED;

list_add_tail(&carveout->node, &rproc->carveouts);

@@ -751,6 +752,27 @@ static int rproc_handle_carveout(struct rproc *rproc,
return ret;
}

+/**
+ * rproc_add_carveout() - register an allocated carveout region
+ * @rproc: rproc handle
+ * @mem: memory entry to register
+ *
+ * This function registers specified memory entry in @rproc carveouts list.
+ * Specified carveout should have been allocated before registering.
+ */
+int rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem)
+{
+ if (!rproc || !mem)
+ return -EINVAL;
+
+ mem->priv = (void *)CARVEOUT_EXTERNAL;
+
+ list_add_tail(&mem->node, &rproc->carveouts);
+
+ return 0;
+}
+EXPORT_SYMBOL(rproc_add_carveout);
+
/*
* A lookup table for resource handlers. The indices are defined in
* enum fw_resource_type.
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index c1077be..69b22ac 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -23,6 +23,13 @@
#include <linux/irqreturn.h>
#include <linux/firmware.h>

+/* Indicate carveout origin */
+enum carveout_src {
+ CARVEOUT_RSC = 0,
+ CARVEOUT_RSC_ALLOCATED = 1,
+ CARVEOUT_EXTERNAL = 2,
+};
+
struct rproc;

/**
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 8780f2e..5bd5175 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -522,6 +522,8 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
int rproc_del(struct rproc *rproc);
void rproc_free(struct rproc *rproc);

+int rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem);
+
int rproc_boot(struct rproc *rproc);
void rproc_shutdown(struct rproc *rproc);
void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
--
1.9.1


From 1586384552303964317@xxx Sun Dec 10 08:23:23 +0000 2017
X-GM-THRID: 1581405651618458163
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread