mm: cma: allocation trigger
[linux-2.6-block.git] / mm / cma_debug.c
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 #include <linux/list.h>
11 #include <linux/kernel.h>
12 #include <linux/slab.h>
13
14 #include "cma.h"
15
16 struct cma_mem {
17         struct hlist_node node;
18         struct page *p;
19         unsigned long n;
20 };
21
22 static struct dentry *cma_debugfs_root;
23
24 static int cma_debugfs_get(void *data, u64 *val)
25 {
26         unsigned long *p = data;
27
28         *val = *p;
29
30         return 0;
31 }
32
33 DEFINE_SIMPLE_ATTRIBUTE(cma_debugfs_fops, cma_debugfs_get, NULL, "%llu\n");
34
35 static void cma_add_to_cma_mem_list(struct cma *cma, struct cma_mem *mem)
36 {
37         spin_lock(&cma->mem_head_lock);
38         hlist_add_head(&mem->node, &cma->mem_head);
39         spin_unlock(&cma->mem_head_lock);
40 }
41
42 static int cma_alloc_mem(struct cma *cma, int count)
43 {
44         struct cma_mem *mem;
45         struct page *p;
46
47         mem = kzalloc(sizeof(*mem), GFP_KERNEL);
48         if (!mem)
49                 return -ENOMEM;
50
51         p = cma_alloc(cma, count, CONFIG_CMA_ALIGNMENT);
52         if (!p) {
53                 kfree(mem);
54                 return -ENOMEM;
55         }
56
57         mem->p = p;
58         mem->n = count;
59
60         cma_add_to_cma_mem_list(cma, mem);
61
62         return 0;
63 }
64
65 static int cma_alloc_write(void *data, u64 val)
66 {
67         int pages = val;
68         struct cma *cma = data;
69
70         return cma_alloc_mem(cma, pages);
71 }
72
73 DEFINE_SIMPLE_ATTRIBUTE(cma_alloc_fops, NULL, cma_alloc_write, "%llu\n");
74
75 static void cma_debugfs_add_one(struct cma *cma, int idx)
76 {
77         struct dentry *tmp;
78         char name[16];
79         int u32s;
80
81         sprintf(name, "cma-%d", idx);
82
83         tmp = debugfs_create_dir(name, cma_debugfs_root);
84
85         debugfs_create_file("alloc", S_IWUSR, cma_debugfs_root, cma,
86                                 &cma_alloc_fops);
87
88         debugfs_create_file("base_pfn", S_IRUGO, tmp,
89                                 &cma->base_pfn, &cma_debugfs_fops);
90         debugfs_create_file("count", S_IRUGO, tmp,
91                                 &cma->count, &cma_debugfs_fops);
92         debugfs_create_file("order_per_bit", S_IRUGO, tmp,
93                                 &cma->order_per_bit, &cma_debugfs_fops);
94
95         u32s = DIV_ROUND_UP(cma_bitmap_maxno(cma), BITS_PER_BYTE * sizeof(u32));
96         debugfs_create_u32_array("bitmap", S_IRUGO, tmp, (u32*)cma->bitmap, u32s);
97 }
98
99 static int __init cma_debugfs_init(void)
100 {
101         int i;
102
103         cma_debugfs_root = debugfs_create_dir("cma", NULL);
104         if (!cma_debugfs_root)
105                 return -ENOMEM;
106
107         for (i = 0; i < cma_area_count; i++)
108                 cma_debugfs_add_one(&cma_areas[i], i);
109
110         return 0;
111 }
112 late_initcall(cma_debugfs_init);