aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSasha Levin <sasha.levin@oracle.com>2015-04-14 18:44:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 19:49:00 -0400
commit28b24c1fc8c22cabe5b8a16ffe6a61dfce51a1f2 (patch)
tree2a6127decc749a3aea6a50123855ba73013fd082
parent19c07d5e0414261bd7ec3d8419dd26f468ef69d9 (diff)
mm: cma: debugfs interface
I've noticed that there is no interfaces exposed by CMA which would let me fuzz what's going on in there. This small patchset exposes some information out to userspace, plus adds the ability to trigger allocation and freeing from userspace. This patch (of 3): Implement a simple debugfs interface to expose information about CMA areas in the system. Useful for testing/sanity checks for CMA since it was impossible to previously retrieve this information in userspace. Signed-off-by: Sasha Levin <sasha.levin@oracle.com> Acked-by: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Marek Szyprowski <m.szyprowski@samsung.com> Cc: Laura Abbott <lauraa@codeaurora.org> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/Kconfig6
-rw-r--r--mm/Makefile1
-rw-r--r--mm/cma.c19
-rw-r--r--mm/cma.h20
-rw-r--r--mm/cma_debug.c60
5 files changed, 91 insertions, 15 deletions
diff --git a/mm/Kconfig b/mm/Kconfig
index a03131b6ba8e..390214da4546 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -517,6 +517,12 @@ config CMA_DEBUG
517 processing calls such as dma_alloc_from_contiguous(). 517 processing calls such as dma_alloc_from_contiguous().
518 This option does not affect warning and error messages. 518 This option does not affect warning and error messages.
519 519
520config CMA_DEBUGFS
521 bool "CMA debugfs interface"
522 depends on CMA && DEBUG_FS
523 help
524 Turns on the DebugFS interface for CMA.
525
520config CMA_AREAS 526config CMA_AREAS
521 int "Maximum count of the CMA areas" 527 int "Maximum count of the CMA areas"
522 depends on CMA 528 depends on CMA
diff --git a/mm/Makefile b/mm/Makefile
index 15dbe9903c27..668a9bb82be4 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -76,3 +76,4 @@ obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o
76obj-$(CONFIG_CMA) += cma.o 76obj-$(CONFIG_CMA) += cma.o
77obj-$(CONFIG_MEMORY_BALLOON) += balloon_compaction.o 77obj-$(CONFIG_MEMORY_BALLOON) += balloon_compaction.o
78obj-$(CONFIG_PAGE_EXTENSION) += page_ext.o 78obj-$(CONFIG_PAGE_EXTENSION) += page_ext.o
79obj-$(CONFIG_CMA_DEBUGFS) += cma_debug.o
diff --git a/mm/cma.c b/mm/cma.c
index 68ecb7a42983..2655b8191656 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -35,16 +35,10 @@
35#include <linux/highmem.h> 35#include <linux/highmem.h>
36#include <linux/io.h> 36#include <linux/io.h>
37 37
38struct cma { 38#include "cma.h"
39 unsigned long base_pfn; 39
40 unsigned long count; 40struct cma cma_areas[MAX_CMA_AREAS];
41 unsigned long *bitmap; 41unsigned cma_area_count;
42 unsigned int order_per_bit; /* Order of pages represented by one bit */
43 struct mutex lock;
44};
45
46static struct cma cma_areas[MAX_CMA_AREAS];
47static unsigned cma_area_count;
48static DEFINE_MUTEX(cma_mutex); 42static DEFINE_MUTEX(cma_mutex);
49 43
50phys_addr_t cma_get_base(struct cma *cma) 44phys_addr_t cma_get_base(struct cma *cma)
@@ -77,11 +71,6 @@ static unsigned long cma_bitmap_aligned_offset(struct cma *cma, int align_order)
77 - cma->base_pfn) >> cma->order_per_bit; 71 - cma->base_pfn) >> cma->order_per_bit;
78} 72}
79 73
80static unsigned long cma_bitmap_maxno(struct cma *cma)
81{
82 return cma->count >> cma->order_per_bit;
83}
84
85static unsigned long cma_bitmap_pages_to_bits(struct cma *cma, 74static unsigned long cma_bitmap_pages_to_bits(struct cma *cma,
86 unsigned long pages) 75 unsigned long pages)
87{ 76{
diff --git a/mm/cma.h b/mm/cma.h
new file mode 100644
index 000000000000..4141887bbfb0
--- /dev/null
+++ b/mm/cma.h
@@ -0,0 +1,20 @@
1#ifndef __MM_CMA_H__
2#define __MM_CMA_H__
3
4struct cma {
5 unsigned long base_pfn;
6 unsigned long count;
7 unsigned long *bitmap;
8 unsigned int order_per_bit; /* Order of pages represented by one bit */
9 struct mutex lock;
10};
11
12extern struct cma cma_areas[MAX_CMA_AREAS];
13extern unsigned cma_area_count;
14
15static unsigned long cma_bitmap_maxno(struct cma *cma)
16{
17 return cma->count >> cma->order_per_bit;
18}
19
20#endif
diff --git a/mm/cma_debug.c b/mm/cma_debug.c
new file mode 100644
index 000000000000..3af2de6d4e5f
--- /dev/null
+++ b/mm/cma_debug.c
@@ -0,0 +1,60 @@
1/*
2 * CMA DebugFS Interface
3 *
4 * Copyright (c) 2015 Sasha Levin <sasha.levin@oracle.com>
5 */
6
7
8#include <linux/debugfs.h>
9#include <linux/cma.h>
10
11#include "cma.h"
12
13static struct dentry *cma_debugfs_root;
14
15static int cma_debugfs_get(void *data, u64 *val)
16{
17 unsigned long *p = data;
18
19 *val = *p;
20
21 return 0;
22}
23
24DEFINE_SIMPLE_ATTRIBUTE(cma_debugfs_fops, cma_debugfs_get, NULL, "%llu\n");
25
26static void cma_debugfs_add_one(struct cma *cma, int idx)
27{
28 struct dentry *tmp;
29 char name[16];
30 int u32s;
31
32 sprintf(name, "cma-%d", idx);
33
34 tmp = debugfs_create_dir(name, cma_debugfs_root);
35
36 debugfs_create_file("base_pfn", S_IRUGO, tmp,
37 &cma->base_pfn, &cma_debugfs_fops);
38 debugfs_create_file("count", S_IRUGO, tmp,
39 &cma->count, &cma_debugfs_fops);
40 debugfs_create_file("order_per_bit", S_IRUGO, tmp,
41 &cma->order_per_bit, &cma_debugfs_fops);
42
43 u32s = DIV_ROUND_UP(cma_bitmap_maxno(cma), BITS_PER_BYTE * sizeof(u32));
44 debugfs_create_u32_array("bitmap", S_IRUGO, tmp, (u32*)cma->bitmap, u32s);
45}
46
47static int __init cma_debugfs_init(void)
48{
49 int i;
50
51 cma_debugfs_root = debugfs_create_dir("cma", NULL);
52 if (!cma_debugfs_root)
53 return -ENOMEM;
54
55 for (i = 0; i < cma_area_count; i++)
56 cma_debugfs_add_one(&cma_areas[i], i);
57
58 return 0;
59}
60late_initcall(cma_debugfs_init);