aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorDan Streetman <ddstreet@ieee.org>2014-08-06 19:08:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 21:01:23 -0400
commitc795779df29e180738568d2a5eb3a42f3b5e47f0 (patch)
tree920f3d48aa48b68801c0ce8dabb67b757850b58d /mm
parentaf8d417a04564bca0348e7e3c749ab12a3e837ad (diff)
mm/zpool: zbud/zsmalloc implement zpool
Update zbud and zsmalloc to implement the zpool api. [fengguang.wu@intel.com: make functions static] Signed-off-by: Dan Streetman <ddstreet@ieee.org> Tested-by: Seth Jennings <sjennings@variantweb.net> Cc: Minchan Kim <minchan@kernel.org> Cc: Nitin Gupta <ngupta@vflare.org> Cc: Weijie Yang <weijie.yang@samsung.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/zbud.c94
-rw-r--r--mm/zsmalloc.c85
2 files changed, 179 insertions, 0 deletions
diff --git a/mm/zbud.c b/mm/zbud.c
index d01226117b8d..a05790b1915e 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -51,6 +51,7 @@
51#include <linux/slab.h> 51#include <linux/slab.h>
52#include <linux/spinlock.h> 52#include <linux/spinlock.h>
53#include <linux/zbud.h> 53#include <linux/zbud.h>
54#include <linux/zpool.h>
54 55
55/***************** 56/*****************
56 * Structures 57 * Structures
@@ -113,6 +114,90 @@ struct zbud_header {
113}; 114};
114 115
115/***************** 116/*****************
117 * zpool
118 ****************/
119
120#ifdef CONFIG_ZPOOL
121
122static int zbud_zpool_evict(struct zbud_pool *pool, unsigned long handle)
123{
124 return zpool_evict(pool, handle);
125}
126
127static struct zbud_ops zbud_zpool_ops = {
128 .evict = zbud_zpool_evict
129};
130
131static void *zbud_zpool_create(gfp_t gfp, struct zpool_ops *zpool_ops)
132{
133 return zbud_create_pool(gfp, &zbud_zpool_ops);
134}
135
136static void zbud_zpool_destroy(void *pool)
137{
138 zbud_destroy_pool(pool);
139}
140
141static int zbud_zpool_malloc(void *pool, size_t size, gfp_t gfp,
142 unsigned long *handle)
143{
144 return zbud_alloc(pool, size, gfp, handle);
145}
146static void zbud_zpool_free(void *pool, unsigned long handle)
147{
148 zbud_free(pool, handle);
149}
150
151static int zbud_zpool_shrink(void *pool, unsigned int pages,
152 unsigned int *reclaimed)
153{
154 unsigned int total = 0;
155 int ret = -EINVAL;
156
157 while (total < pages) {
158 ret = zbud_reclaim_page(pool, 8);
159 if (ret < 0)
160 break;
161 total++;
162 }
163
164 if (reclaimed)
165 *reclaimed = total;
166
167 return ret;
168}
169
170static void *zbud_zpool_map(void *pool, unsigned long handle,
171 enum zpool_mapmode mm)
172{
173 return zbud_map(pool, handle);
174}
175static void zbud_zpool_unmap(void *pool, unsigned long handle)
176{
177 zbud_unmap(pool, handle);
178}
179
180static u64 zbud_zpool_total_size(void *pool)
181{
182 return zbud_get_pool_size(pool) * PAGE_SIZE;
183}
184
185static struct zpool_driver zbud_zpool_driver = {
186 .type = "zbud",
187 .owner = THIS_MODULE,
188 .create = zbud_zpool_create,
189 .destroy = zbud_zpool_destroy,
190 .malloc = zbud_zpool_malloc,
191 .free = zbud_zpool_free,
192 .shrink = zbud_zpool_shrink,
193 .map = zbud_zpool_map,
194 .unmap = zbud_zpool_unmap,
195 .total_size = zbud_zpool_total_size,
196};
197
198#endif /* CONFIG_ZPOOL */
199
200/*****************
116 * Helpers 201 * Helpers
117*****************/ 202*****************/
118/* Just to make the code easier to read */ 203/* Just to make the code easier to read */
@@ -511,11 +596,20 @@ static int __init init_zbud(void)
511 /* Make sure the zbud header will fit in one chunk */ 596 /* Make sure the zbud header will fit in one chunk */
512 BUILD_BUG_ON(sizeof(struct zbud_header) > ZHDR_SIZE_ALIGNED); 597 BUILD_BUG_ON(sizeof(struct zbud_header) > ZHDR_SIZE_ALIGNED);
513 pr_info("loaded\n"); 598 pr_info("loaded\n");
599
600#ifdef CONFIG_ZPOOL
601 zpool_register_driver(&zbud_zpool_driver);
602#endif
603
514 return 0; 604 return 0;
515} 605}
516 606
517static void __exit exit_zbud(void) 607static void __exit exit_zbud(void)
518{ 608{
609#ifdef CONFIG_ZPOOL
610 zpool_unregister_driver(&zbud_zpool_driver);
611#endif
612
519 pr_info("unloaded\n"); 613 pr_info("unloaded\n");
520} 614}
521 615
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 6a1827d3d231..4e2fc83cb394 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -92,6 +92,7 @@
92#include <linux/spinlock.h> 92#include <linux/spinlock.h>
93#include <linux/types.h> 93#include <linux/types.h>
94#include <linux/zsmalloc.h> 94#include <linux/zsmalloc.h>
95#include <linux/zpool.h>
95 96
96/* 97/*
97 * This must be power of 2 and greater than of equal to sizeof(link_free). 98 * This must be power of 2 and greater than of equal to sizeof(link_free).
@@ -240,6 +241,82 @@ struct mapping_area {
240 enum zs_mapmode vm_mm; /* mapping mode */ 241 enum zs_mapmode vm_mm; /* mapping mode */
241}; 242};
242 243
244/* zpool driver */
245
246#ifdef CONFIG_ZPOOL
247
248static void *zs_zpool_create(gfp_t gfp, struct zpool_ops *zpool_ops)
249{
250 return zs_create_pool(gfp);
251}
252
253static void zs_zpool_destroy(void *pool)
254{
255 zs_destroy_pool(pool);
256}
257
258static int zs_zpool_malloc(void *pool, size_t size, gfp_t gfp,
259 unsigned long *handle)
260{
261 *handle = zs_malloc(pool, size);
262 return *handle ? 0 : -1;
263}
264static void zs_zpool_free(void *pool, unsigned long handle)
265{
266 zs_free(pool, handle);
267}
268
269static int zs_zpool_shrink(void *pool, unsigned int pages,
270 unsigned int *reclaimed)
271{
272 return -EINVAL;
273}
274
275static void *zs_zpool_map(void *pool, unsigned long handle,
276 enum zpool_mapmode mm)
277{
278 enum zs_mapmode zs_mm;
279
280 switch (mm) {
281 case ZPOOL_MM_RO:
282 zs_mm = ZS_MM_RO;
283 break;
284 case ZPOOL_MM_WO:
285 zs_mm = ZS_MM_WO;
286 break;
287 case ZPOOL_MM_RW: /* fallthru */
288 default:
289 zs_mm = ZS_MM_RW;
290 break;
291 }
292
293 return zs_map_object(pool, handle, zs_mm);
294}
295static void zs_zpool_unmap(void *pool, unsigned long handle)
296{
297 zs_unmap_object(pool, handle);
298}
299
300static u64 zs_zpool_total_size(void *pool)
301{
302 return zs_get_total_size_bytes(pool);
303}
304
305static struct zpool_driver zs_zpool_driver = {
306 .type = "zsmalloc",
307 .owner = THIS_MODULE,
308 .create = zs_zpool_create,
309 .destroy = zs_zpool_destroy,
310 .malloc = zs_zpool_malloc,
311 .free = zs_zpool_free,
312 .shrink = zs_zpool_shrink,
313 .map = zs_zpool_map,
314 .unmap = zs_zpool_unmap,
315 .total_size = zs_zpool_total_size,
316};
317
318#endif /* CONFIG_ZPOOL */
319
243/* per-cpu VM mapping areas for zspage accesses that cross page boundaries */ 320/* per-cpu VM mapping areas for zspage accesses that cross page boundaries */
244static DEFINE_PER_CPU(struct mapping_area, zs_map_area); 321static DEFINE_PER_CPU(struct mapping_area, zs_map_area);
245 322
@@ -813,6 +890,10 @@ static void zs_exit(void)
813{ 890{
814 int cpu; 891 int cpu;
815 892
893#ifdef CONFIG_ZPOOL
894 zpool_unregister_driver(&zs_zpool_driver);
895#endif
896
816 cpu_notifier_register_begin(); 897 cpu_notifier_register_begin();
817 898
818 for_each_online_cpu(cpu) 899 for_each_online_cpu(cpu)
@@ -839,6 +920,10 @@ static int zs_init(void)
839 920
840 cpu_notifier_register_done(); 921 cpu_notifier_register_done();
841 922
923#ifdef CONFIG_ZPOOL
924 zpool_register_driver(&zs_zpool_driver);
925#endif
926
842 return 0; 927 return 0;
843fail: 928fail:
844 zs_exit(); 929 zs_exit();