* [PATCH v4 RESEND] mm: cma: add a simple kernel module as the helper to test CMA
@ 2012-07-05 6:24 Barry Song
2012-07-05 8:09 ` Arnd Bergmann
0 siblings, 1 reply; 3+ messages in thread
From: Barry Song @ 2012-07-05 6:24 UTC (permalink / raw)
To: linux-arm-kernel
From: Barry Song <Baohua.Song@csr.com>
Any write request to /dev/cma_test will let the module to allocate memory from
CMA, for example:
1st time
$ echo 1024 > /dev/cma_test
will require cma_test to request 1MB(1024KB)
2nd time
$ echo 2048 > /dev/cma_test
will require cma_test to request 2MB(2048KB)
Any read request to /dev/cma_test will let the module to free the 1st valid
memory from CMA, for example:
1st time
$ cat /dev/cma_test
will require cma_test to free the 1MB allocated in the first write request
2nd time
$ cat /dev/cma_test
will require cma_test to free the 2MB allocated in the second write request
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Reviewed-by: Michal Nazarewicz <mina86@mina86.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
resend to Greg KH so that he can decide whether it should be placed at tools
or drivers/misc;
See the discussion thread:
[1] https://lkml.org/lkml/2012/7/3/80
[2] https://lkml.org/lkml/2012/7/3/224
[3] https://lkml.org/lkml/2012/7/4/87
tools/cma/Makefile | 13 +++++
tools/cma/cma_test.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 153 insertions(+), 0 deletions(-)
create mode 100644 tools/cma/Makefile
create mode 100644 tools/cma/cma_test.c
diff --git a/tools/cma/Makefile b/tools/cma/Makefile
new file mode 100644
index 0000000..d15c2c0
--- /dev/null
+++ b/tools/cma/Makefile
@@ -0,0 +1,13 @@
+# Kernel modules
+#
+# To compile for ARM:
+# make ARCH=arm CC=arm-none-linux-gnueabi-gcc
+#
+obj-m += cma_test.o
+
+build: kernel_modules
+
+kernel_modules:
+ ${MAKE} -C $(CURDIR)/../.. M=$(CURDIR)
+clean:
+ ${MAKE} -C $(CURDIR)/../.. M=$(CURDIR) clean
diff --git a/tools/cma/cma_test.c b/tools/cma/cma_test.c
new file mode 100644
index 0000000..7eb96db
--- /dev/null
+++ b/tools/cma/cma_test.c
@@ -0,0 +1,140 @@
+/*
+ * kernel module helper for testing CMA
+ *
+ * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+struct cma_allocation {
+ struct list_head list;
+ size_t size;
+ dma_addr_t dma;
+ void *virt;
+};
+
+static struct device *cma_dev;
+static LIST_HEAD(cma_allocations);
+static DEFINE_SPINLOCK(cma_lock);
+
+/*
+ * any read request will free the 1st allocated coherent memory, eg.
+ * cat /dev/cma_test
+ */
+static ssize_t
+cma_test_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+ struct cma_allocation *alloc = NULL;
+
+ spin_lock(&cma_lock);
+ if (!list_empty(&cma_allocations)) {
+ alloc = list_first_entry(&cma_allocations,
+ struct cma_allocation, list);
+ list_del(&alloc->list);
+ }
+ spin_unlock(&cma_lock);
+
+ if (!alloc)
+ return -EIDRM;
+
+ dma_free_coherent(cma_dev, alloc->size, alloc->virt,
+ alloc->dma);
+
+ _dev_info(cma_dev, "free: CM virt: %p dma: %p size:%zuK\n",
+ alloc->virt, (void *)alloc->dma, alloc->size / SZ_1K);
+ kfree(alloc);
+
+ return 0;
+}
+
+/*
+ * any write request will alloc a new coherent memory, eg.
+ * echo 1024 > /dev/cma_test
+ * will request 1024KiB by CMA
+ */
+static ssize_t
+cma_test_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{
+ struct cma_allocation *alloc;
+ unsigned long size;
+ int ret;
+
+ ret = kstrtoul_from_user(buf, count, 0, &size);
+ if (ret)
+ return ret;
+
+ if (!size)
+ return -EINVAL;
+
+ if (size > ~(size_t)0 / SZ_1K)
+ return -EOVERFLOW;
+
+ alloc = kmalloc(sizeof *alloc, GFP_KERNEL);
+ if (!alloc)
+ return -ENOMEM;
+
+ alloc->size = size * SZ_1K;
+ alloc->virt = dma_alloc_coherent(cma_dev, alloc->size,
+ &alloc->dma, GFP_KERNEL);
+
+ if (alloc->virt) {
+ _dev_info(cma_dev, "alloc: virt: %p dma: %p size: %zuK\n",
+ alloc->virt, (void *)alloc->dma, alloc->size / SZ_1K);
+
+ spin_lock(&cma_lock);
+ list_add_tail(&alloc->list, &cma_allocations);
+ spin_unlock(&cma_lock);
+
+ return count;
+ } else {
+ dev_err(cma_dev, "no mem in CMA area\n");
+ kfree(alloc);
+ return -ENOSPC;
+ }
+}
+
+static const struct file_operations cma_test_fops = {
+ .owner = THIS_MODULE,
+ .read = cma_test_read,
+ .write = cma_test_write,
+};
+
+static struct miscdevice cma_test_misc = {
+ .name = "cma_test",
+ .fops = &cma_test_fops,
+};
+
+static int __init cma_test_init(void)
+{
+ int ret = misc_register(&cma_test_misc);
+
+ if (unlikely(ret)) {
+ pr_err("failed to register cma test misc device!\n");
+ return ret;
+ }
+ cma_dev = cma_test_misc.this_device;
+ cma_dev->coherent_dma_mask = ~0;
+ _dev_info(cma_dev, "registered.\n");
+
+ return 0;
+}
+module_init(cma_test_init);
+
+static void __exit cma_test_exit(void)
+{
+ misc_deregister(&cma_test_misc);
+}
+module_exit(cma_test_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Barry Song <Baohua.Song@csr.com>");
+MODULE_DESCRIPTION("kernel module to help the test of CMA");
+MODULE_ALIAS("cma_test");
--
1.7.1
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH v4 RESEND] mm: cma: add a simple kernel module as the helper to test CMA
2012-07-05 6:24 [PATCH v4 RESEND] mm: cma: add a simple kernel module as the helper to test CMA Barry Song
@ 2012-07-05 8:09 ` Arnd Bergmann
2012-07-05 8:44 ` Barry Song
0 siblings, 1 reply; 3+ messages in thread
From: Arnd Bergmann @ 2012-07-05 8:09 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 05 July 2012, Barry Song wrote:
> From: Barry Song <Baohua.Song@csr.com>
>
> Any write request to /dev/cma_test will let the module to allocate memory from
> CMA, for example:
>
> 1st time
> $ echo 1024 > /dev/cma_test
> will require cma_test to request 1MB(1024KB)
> 2nd time
> $ echo 2048 > /dev/cma_test
> will require cma_test to request 2MB(2048KB)
>
> Any read request to /dev/cma_test will let the module to free the 1st valid
> memory from CMA, for example:
>
> 1st time
> $ cat /dev/cma_test
> will require cma_test to free the 1MB allocated in the first write request
> 2nd time
> $ cat /dev/cma_test
> will require cma_test to free the 2MB allocated in the second write request
I missed the earlier times this was posted and read up on it now.
> Signed-off-by: Barry Song <Baohua.Song@csr.com>
> Reviewed-by: Michal Nazarewicz <mina86@mina86.com>
> Cc: Marek Szyprowski <m.szyprowski@samsung.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
> resend to Greg KH so that he can decide whether it should be placed at tools
> or drivers/misc;
> See the discussion thread:
> [1] https://lkml.org/lkml/2012/7/3/80
> [2] https://lkml.org/lkml/2012/7/3/224
> [3] https://lkml.org/lkml/2012/7/4/87
I think it should be in mm/cma-test.c, along with kmemleak-test.c. It would be nice
if you could add some code that just runs at boot time (or when the module is
loaded) and allocates and frees memory using CMA.
> +static struct device *cma_dev;
Do you actually need this device? It's not connected to hardware so
it doesn't actually do DMA and we might as well pass a NULL pointer
into dma_alloc_*().
> +static const struct file_operations cma_test_fops = {
> + .owner = THIS_MODULE,
> + .read = cma_test_read,
> + .write = cma_test_write,
> +};
> +
> +static struct miscdevice cma_test_misc = {
> + .name = "cma_test",
> + .fops = &cma_test_fops,
> +};
> +
> +static int __init cma_test_init(void)
> +{
> + int ret = misc_register(&cma_test_misc);
A better place for this is really debugfs. The driver is not meant as a stable
kernel interface that applications can rely on, it's purely a debugging help.
Just make this
ret = debugfs_create_file("cma-test", 0600, NULL, NULL, &cma_test_fops);
Arnd
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH v4 RESEND] mm: cma: add a simple kernel module as the helper to test CMA
2012-07-05 8:09 ` Arnd Bergmann
@ 2012-07-05 8:44 ` Barry Song
0 siblings, 0 replies; 3+ messages in thread
From: Barry Song @ 2012-07-05 8:44 UTC (permalink / raw)
To: linux-arm-kernel
Hi Arnd,
2012/7/5 Arnd Bergmann <arnd@arndb.de>:
>
> I think it should be in mm/cma-test.c, along with kmemleak-test.c. It would be nice
> if you could add some code that just runs at boot time (or when the module is
> loaded) and allocates and frees memory using CMA.
>
>> +static struct device *cma_dev;
>
> Do you actually need this device? It's not connected to hardware so
> it doesn't actually do DMA and we might as well pass a NULL pointer
> into dma_alloc_*().
>
>> +static const struct file_operations cma_test_fops = {
>> + .owner = THIS_MODULE,
>> + .read = cma_test_read,
>> + .write = cma_test_write,
>> +};
>> +
>> +static struct miscdevice cma_test_misc = {
>> + .name = "cma_test",
>> + .fops = &cma_test_fops,
>> +};
>> +
>> +static int __init cma_test_init(void)
>> +{
>> + int ret = misc_register(&cma_test_misc);
>
> A better place for this is really debugfs. The driver is not meant as a stable
> kernel interface that applications can rely on, it's purely a debugging help.
>
> Just make this
>
> ret = debugfs_create_file("cma-test", 0600, NULL, NULL, &cma_test_fops);
>
we did have some discussions about this at:
http://www.spinics.net/lists/arm-kernel/msg163548.html
i'd say both are acceptable to me.
> Arnd
>
-barry
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-07-05 8:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-05 6:24 [PATCH v4 RESEND] mm: cma: add a simple kernel module as the helper to test CMA Barry Song
2012-07-05 8:09 ` Arnd Bergmann
2012-07-05 8:44 ` Barry Song
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).