23 #include <linux/module.h>
26 #include <linux/list.h>
27 #include <linux/slab.h>
29 #include <linux/types.h>
33 #include <linux/string.h>
37 #include "../zsmalloc/zsmalloc.h"
39 #ifdef CONFIG_CLEANCACHE
42 #ifdef CONFIG_FRONTSWAP
48 #define ZCACHE_GFP_MASK (GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN)
50 #define ZCACHE_GFP_MASK \
51 (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC)
54 #define MAX_CLIENTS 16
55 #define LOCAL_CLIENT ((uint16_t)-1)
72 if (cli == &zcache_host)
74 return cli - &zcache_clients[0];
83 return &zcache_clients[cli_id];
90 return cli == &zcache_host;
94 #define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME
103 static inline int zcache_comp_op(
enum comp_op op,
104 const u8 *
src,
unsigned int slen,
110 BUG_ON(!zcache_comp_pcpu_tfms);
115 ret = crypto_comp_compress(tfm, src, slen, dst, dlen);
118 ret = crypto_comp_decompress(tfm, src, slen, dst, dlen);
144 #define ZBH_SENTINEL 0x43214321
145 #define ZBPG_SENTINEL 0xdeadbeef
147 #define ZBUD_MAX_BUDS 2
166 #define CHUNK_SHIFT 6
167 #define CHUNK_SIZE (1 << CHUNK_SHIFT)
168 #define CHUNK_MASK (~(CHUNK_SIZE-1))
169 #define NCHUNKS (((PAGE_SIZE - sizeof(struct zbud_page)) & \
170 CHUNK_MASK) >> CHUNK_SHIFT)
171 #define MAX_CHUNK (NCHUNKS-1)
179 static unsigned long zbud_cumul_chunk_counts[
NCHUNKS];
182 static unsigned long zcache_zbud_buddied_count;
188 static unsigned long zcache_zbpg_unused_list_count;
193 static atomic_t zcache_zbud_curr_raw_pages;
194 static atomic_t zcache_zbud_curr_zpages;
195 static unsigned long zcache_zbud_curr_zbytes;
196 static unsigned long zcache_zbud_cumul_zpages;
197 static unsigned long zcache_zbud_cumul_zbytes;
198 static unsigned long zcache_compress_poor;
199 static unsigned long zcache_mean_compress_poor;
202 static void *zcache_get_free_page(
void);
203 static void zcache_free_page(
void *
p);
214 static inline unsigned zbud_size_to_chunks(
unsigned size)
220 static inline int zbud_budnum(
struct zbud_hdr *zh)
224 unsigned budnum = -1
U;
236 static char *zbud_data(
struct zbud_hdr *zh,
unsigned size)
243 budnum = zbud_budnum(zh);
251 else if (budnum == 1)
260 static struct zbud_page *zbud_alloc_raw_page(
void)
267 spin_lock(&zbpg_unused_list_spinlock);
268 if (!list_empty(&zbpg_unused_list)) {
272 zcache_zbpg_unused_list_count--;
275 spin_unlock(&zbpg_unused_list_spinlock);
278 zbpg = zcache_get_free_page();
293 tmem_oid_set_invalid(&zh0->
oid);
294 tmem_oid_set_invalid(&zh1->
oid);
300 static void zbud_free_raw_page(
struct zbud_page *zbpg)
310 spin_unlock(&zbpg->
lock);
311 spin_lock(&zbpg_unused_list_spinlock);
312 list_add(&zbpg->
bud_list, &zbpg_unused_list);
313 zcache_zbpg_unused_list_count++;
314 spin_unlock(&zbpg_unused_list_spinlock);
321 static unsigned zbud_free(
struct zbud_hdr *zh)
330 tmem_oid_set_invalid(&zh->
oid);
332 zcache_zbud_curr_zbytes -=
size;
341 unsigned budnum = zbud_budnum(zh),
size;
345 spin_lock(&zbud_budlists_spinlock);
346 spin_lock(&zbpg->
lock);
349 spin_unlock(&zbpg->
lock);
350 spin_unlock(&zbud_budlists_spinlock);
353 size = zbud_free(zh);
355 zh_other = &zbpg->
buddy[(budnum == 0) ? 1 : 0];
356 if (zh_other->
size == 0) {
357 chunks = zbud_size_to_chunks(size) ;
361 spin_unlock(&zbud_budlists_spinlock);
362 zbud_free_raw_page(zbpg);
364 chunks = zbud_size_to_chunks(zh_other->
size) ;
366 zcache_zbud_buddied_count--;
369 spin_unlock(&zbud_budlists_spinlock);
370 spin_unlock(&zbpg->
lock);
377 void *
cdata,
unsigned size)
383 int i, found_good_buddy = 0;
385 nchunks = zbud_size_to_chunks(size) ;
386 for (i =
MAX_CHUNK - nchunks + 1; i > 0; i--) {
387 spin_lock(&zbud_budlists_spinlock);
391 if (spin_trylock(&zbpg->
lock)) {
392 found_good_buddy =
i;
393 goto found_unbuddied;
397 spin_unlock(&zbud_budlists_spinlock);
400 zbpg = zbud_alloc_raw_page();
404 spin_lock(&zbud_budlists_spinlock);
405 spin_lock(&zbpg->
lock);
408 zh = &zbpg->
buddy[0];
415 if (zh0->
size != 0) {
418 }
else if (zh1->
size != 0) {
426 zcache_zbud_buddied_count++;
435 to = zbud_data(zh, size);
437 spin_unlock(&zbpg->
lock);
438 spin_unlock(&zbud_budlists_spinlock);
440 zbud_cumul_chunk_counts[nchunks]++;
442 zcache_zbud_cumul_zpages++;
443 zcache_zbud_curr_zbytes +=
size;
444 zcache_zbud_cumul_zbytes +=
size;
452 unsigned budnum = zbud_budnum(zh);
454 char *to_va, *from_va;
459 spin_lock(&zbpg->
lock);
469 from_va = zbud_data(zh, size);
476 spin_unlock(&zbpg->
lock);
485 static unsigned long zcache_evicted_raw_pages;
486 static unsigned long zcache_evicted_buddied_pages;
487 static unsigned long zcache_evicted_unbuddied_pages;
496 static void zbud_evict_zbpg(
struct zbud_page *zbpg)
518 spin_unlock(&zbpg->
lock);
519 for (i = 0; i <
j; i++) {
527 spin_lock(&zbpg->
lock);
528 zbud_free_raw_page(zbpg);
539 static void zbud_evict_pages(
int nr)
546 spin_lock_bh(&zbpg_unused_list_spinlock);
547 if (!list_empty(&zbpg_unused_list)) {
552 zcache_zbpg_unused_list_count--;
554 spin_unlock_bh(&zbpg_unused_list_spinlock);
555 zcache_free_page(zbpg);
556 zcache_evicted_raw_pages++;
559 goto retry_unused_list;
561 spin_unlock_bh(&zbpg_unused_list_spinlock);
566 spin_lock_bh(&zbud_budlists_spinlock);
568 spin_unlock_bh(&zbud_budlists_spinlock);
576 spin_unlock(&zbud_budlists_spinlock);
577 zcache_evicted_unbuddied_pages++;
579 zbud_evict_zbpg(zbpg);
583 goto retry_unbud_list_i;
585 spin_unlock_bh(&zbud_budlists_spinlock);
590 spin_lock_bh(&zbud_budlists_spinlock);
592 spin_unlock_bh(&zbud_budlists_spinlock);
599 zcache_zbud_buddied_count--;
600 spin_unlock(&zbud_budlists_spinlock);
601 zcache_evicted_buddied_pages++;
603 zbud_evict_zbpg(zbpg);
609 spin_unlock_bh(&zbud_budlists_spinlock);
630 static int zbud_show_unbuddied_list_counts(
char *
buf)
640 static int zbud_show_cumul_chunk_counts(
char *buf)
642 unsigned long i, chunks = 0, total_chunks = 0, sum_total_chunks = 0;
643 unsigned long total_chunks_lte_21 = 0, total_chunks_lte_32 = 0;
644 unsigned long total_chunks_lte_42 = 0;
647 for (i = 0; i <
NCHUNKS; i++) {
648 p +=
sprintf(p,
"%lu ", zbud_cumul_chunk_counts[i]);
649 chunks += zbud_cumul_chunk_counts[
i];
650 total_chunks += zbud_cumul_chunk_counts[
i];
651 sum_total_chunks += i * zbud_cumul_chunk_counts[
i];
653 total_chunks_lte_21 = total_chunks;
655 total_chunks_lte_32 = total_chunks;
657 total_chunks_lte_42 = total_chunks;
659 p +=
sprintf(p,
"<=21:%lu <=32:%lu <=42:%lu, mean:%lu\n",
660 total_chunks_lte_21, total_chunks_lte_32, total_chunks_lte_42,
661 chunks == 0 ? 0 : sum_total_chunks / chunks);
675 #define ZVH_SENTINEL 0x43214321
687 static unsigned int zv_page_count_policy_percent = 75;
692 static unsigned int zv_max_zsize = (
PAGE_SIZE / 8) * 7;
698 static unsigned int zv_max_mean_zsize = (
PAGE_SIZE / 8) * 5;
705 void *cdata,
unsigned clen)
713 BUG_ON(chunks >= NCHUNKS);
725 memcpy((
char *)zv +
sizeof(
struct zv_hdr), cdata, clen);
731 static void zv_free(
struct zs_pool *pool,
unsigned long handle)
745 BUG_ON(chunks >= NCHUNKS);
753 static void zv_decompress(
struct page *page,
unsigned long handle)
765 zv->
size, to_va, &clen);
777 static int zv_curr_dist_counts_show(
char *buf)
779 unsigned long i,
n, chunks = 0, sum_total_chunks = 0;
782 for (i = 0; i <
NCHUNKS; i++) {
786 sum_total_chunks += i *
n;
789 chunks == 0 ? 0 : sum_total_chunks / chunks);
793 static int zv_cumul_dist_counts_show(
char *buf)
795 unsigned long i,
n, chunks = 0, sum_total_chunks = 0;
798 for (i = 0; i <
NCHUNKS; i++) {
802 sum_total_chunks += i *
n;
805 chunks == 0 ? 0 : sum_total_chunks / chunks);
819 return sprintf(buf,
"%u\n", zv_max_zsize);
824 const char *buf,
size_t count)
832 err = kstrtoul(buf, 10, &val);
833 if (err || (val == 0) || (val > (
PAGE_SIZE / 8) * 7))
851 return sprintf(buf,
"%u\n", zv_max_mean_zsize);
856 const char *buf,
size_t count)
864 err = kstrtoul(buf, 10, &val);
865 if (err || (val == 0) || (val > (
PAGE_SIZE / 8) * 7))
867 zv_max_mean_zsize =
val;
881 static ssize_t zv_page_count_policy_percent_show(
struct kobject *kobj,
885 return sprintf(buf,
"%u\n", zv_page_count_policy_percent);
888 static ssize_t zv_page_count_policy_percent_store(
struct kobject *kobj,
890 const char *buf,
size_t count)
898 err = kstrtoul(buf, 10, &val);
899 if (err || (val == 0) || (val > 150))
901 zv_page_count_policy_percent =
val;
906 .
attr = { .name =
"zv_max_zsize", .mode = 0644 },
907 .show = zv_max_zsize_show,
908 .store = zv_max_zsize_store,
912 .
attr = { .name =
"zv_max_mean_zsize", .mode = 0644 },
913 .show = zv_max_mean_zsize_show,
914 .store = zv_max_mean_zsize_store,
917 static struct kobj_attribute zcache_zv_page_count_policy_percent_attr = {
918 .
attr = { .name =
"zv_page_count_policy_percent",
920 .show = zv_page_count_policy_percent_show,
921 .store = zv_page_count_policy_percent_store,
930 static unsigned long zcache_flush_total;
931 static unsigned long zcache_flush_found;
932 static unsigned long zcache_flobj_total;
933 static unsigned long zcache_flobj_found;
934 static unsigned long zcache_failed_eph_puts;
935 static unsigned long zcache_failed_pers_puts;
949 cli = get_zcache_client(cli_id);
977 cli = get_zcache_client(cli_id);
984 #ifdef CONFIG_FRONTSWAP
996 static unsigned long zcache_failed_get_free_pages;
997 static unsigned long zcache_failed_alloc;
998 static unsigned long zcache_put_to_flush;
1005 static struct kmem_cache *zcache_objnode_cache;
1008 static unsigned long zcache_curr_obj_count_max;
1010 static unsigned long zcache_curr_objnode_count_max;
1025 static int zcache_do_preload(
struct tmem_pool *pool)
1044 zcache_failed_alloc++;
1054 zcache_failed_alloc++;
1063 zcache_failed_get_free_pages++;
1074 static void *zcache_get_free_page(
void)
1086 static void zcache_free_page(
void *p)
1098 unsigned long count;
1109 if (count > zcache_curr_objnode_count_max)
1110 zcache_curr_objnode_count_max =
count;
1115 static void zcache_objnode_free(
struct tmem_objnode *objnode,
1126 unsigned long count;
1134 if (count > zcache_curr_obj_count_max)
1135 zcache_curr_obj_count_max =
count;
1147 .obj_alloc = zcache_obj_alloc,
1148 .obj_free = zcache_obj_free,
1149 .objnode_alloc = zcache_objnode_alloc,
1150 .objnode_free = zcache_objnode_free,
1158 static unsigned long zcache_curr_eph_pampd_count_max;
1160 static unsigned long zcache_curr_pers_pampd_count_max;
1163 static int zcache_compress(
struct page *
from,
void **out_va,
unsigned *out_len);
1172 unsigned long count;
1173 struct page *page = (
struct page *)(data);
1175 uint16_t client_id = get_client_id_from_client(cli);
1176 unsigned long zv_mean_zsize;
1177 unsigned long curr_pers_pampd_count;
1181 ret = zcache_compress(page, &cdata, &clen);
1185 zcache_compress_poor++;
1188 pampd = (
void *)zbud_create(client_id, pool->
pool_id, oid,
1189 index, page, cdata, clen);
1190 if (pampd !=
NULL) {
1192 if (count > zcache_curr_eph_pampd_count_max)
1193 zcache_curr_eph_pampd_count_max =
count;
1196 curr_pers_pampd_count =
1198 if (curr_pers_pampd_count >
1199 (zv_page_count_policy_percent * totalram_pages) / 100)
1201 ret = zcache_compress(page, &cdata, &clen);
1205 if (clen > zv_max_zsize) {
1206 zcache_compress_poor++;
1210 if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) {
1212 zv_mean_zsize = div_u64(total_zsize,
1213 curr_pers_pampd_count);
1214 if (zv_mean_zsize > zv_max_mean_zsize) {
1215 zcache_mean_compress_poor++;
1220 oid, index, cdata, clen);
1224 if (count > zcache_curr_pers_pampd_count_max)
1225 zcache_curr_pers_pampd_count_max =
count;
1235 static int zcache_pampd_get_data(
char *data,
size_t *
bufsize,
bool raw,
1242 zv_decompress((
struct page *)(data), (
unsigned long)pampd);
1250 static int zcache_pampd_get_data_and_free(
char *data,
size_t *bufsize,
bool raw,
1266 static void zcache_pampd_free(
void *pampd,
struct tmem_pool *pool,
1276 zv_free(cli->
zspool, (
unsigned long)pampd);
1286 static void zcache_pampd_new_obj(
struct tmem_obj *obj)
1290 static int zcache_pampd_replace_in_obj(
void *pampd,
struct tmem_obj *obj)
1295 static bool zcache_pampd_is_remote(
void *pampd)
1302 .get_data = zcache_pampd_get_data,
1303 .get_data_and_free = zcache_pampd_get_data_and_free,
1304 .free = zcache_pampd_free,
1305 .free_obj = zcache_pampd_free_obj,
1306 .new_obj = zcache_pampd_new_obj,
1307 .replace_in_obj = zcache_pampd_replace_in_obj,
1308 .is_remote = zcache_pampd_is_remote,
1316 #define ZCACHE_DSTMEM_ORDER 1
1318 static int zcache_compress(
struct page *
from,
void **out_va,
unsigned *out_len)
1340 static int zcache_comp_cpu_up(
int cpu)
1344 tfm = crypto_alloc_comp(zcache_comp_name, 0, 0);
1351 static void zcache_comp_cpu_down(
int cpu)
1356 crypto_free_comp(tfm);
1368 ret = zcache_comp_cpu_up(cpu);
1369 if (ret != NOTIFY_OK) {
1370 pr_err(
"zcache: can't allocate compressor transform\n");
1378 zcache_comp_cpu_down(cpu);
1382 kp = &
per_cpu(zcache_preloads, cpu);
1405 .notifier_call = zcache_cpu_notifier
1409 #define ZCACHE_SYSFS_RO(_name) \
1410 static ssize_t zcache_##_name##_show(struct kobject *kobj, \
1411 struct kobj_attribute *attr, char *buf) \
1413 return sprintf(buf, "%lu\n", zcache_##_name); \
1415 static struct kobj_attribute zcache_##_name##_attr = { \
1416 .attr = { .name = __stringify(_name), .mode = 0444 }, \
1417 .show = zcache_##_name##_show, \
1420 #define ZCACHE_SYSFS_RO_ATOMIC(_name) \
1421 static ssize_t zcache_##_name##_show(struct kobject *kobj, \
1422 struct kobj_attribute *attr, char *buf) \
1424 return sprintf(buf, "%d\n", atomic_read(&zcache_##_name)); \
1426 static struct kobj_attribute zcache_##_name##_attr = { \
1427 .attr = { .name = __stringify(_name), .mode = 0444 }, \
1428 .show = zcache_##_name##_show, \
1431 #define ZCACHE_SYSFS_RO_CUSTOM(_name, _func) \
1432 static ssize_t zcache_##_name##_show(struct kobject *kobj, \
1433 struct kobj_attribute *attr, char *buf) \
1435 return _func(buf); \
1437 static struct kobj_attribute zcache_##_name##_attr = { \
1438 .attr = { .name = __stringify(_name), .mode = 0444 }, \
1439 .show = zcache_##_name##_show, \
1442 ZCACHE_SYSFS_RO(curr_obj_count_max);
1443 ZCACHE_SYSFS_RO(curr_objnode_count_max);
1444 ZCACHE_SYSFS_RO(flush_total);
1445 ZCACHE_SYSFS_RO(flush_found);
1446 ZCACHE_SYSFS_RO(flobj_total);
1447 ZCACHE_SYSFS_RO(flobj_found);
1448 ZCACHE_SYSFS_RO(failed_eph_puts);
1449 ZCACHE_SYSFS_RO(failed_pers_puts);
1450 ZCACHE_SYSFS_RO(zbud_curr_zbytes);
1451 ZCACHE_SYSFS_RO(zbud_cumul_zpages);
1452 ZCACHE_SYSFS_RO(zbud_cumul_zbytes);
1453 ZCACHE_SYSFS_RO(zbud_buddied_count);
1454 ZCACHE_SYSFS_RO(zbpg_unused_list_count);
1455 ZCACHE_SYSFS_RO(evicted_raw_pages);
1456 ZCACHE_SYSFS_RO(evicted_unbuddied_pages);
1457 ZCACHE_SYSFS_RO(evicted_buddied_pages);
1458 ZCACHE_SYSFS_RO(failed_get_free_pages);
1459 ZCACHE_SYSFS_RO(failed_alloc);
1460 ZCACHE_SYSFS_RO(put_to_flush);
1461 ZCACHE_SYSFS_RO(compress_poor);
1462 ZCACHE_SYSFS_RO(mean_compress_poor);
1463 ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages);
1464 ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages);
1465 ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count);
1466 ZCACHE_SYSFS_RO_ATOMIC(curr_objnode_count);
1467 ZCACHE_SYSFS_RO_CUSTOM(zbud_unbuddied_list_counts,
1468 zbud_show_unbuddied_list_counts);
1469 ZCACHE_SYSFS_RO_CUSTOM(zbud_cumul_chunk_counts,
1470 zbud_show_cumul_chunk_counts);
1471 ZCACHE_SYSFS_RO_CUSTOM(zv_curr_dist_counts,
1472 zv_curr_dist_counts_show);
1473 ZCACHE_SYSFS_RO_CUSTOM(zv_cumul_dist_counts,
1474 zv_cumul_dist_counts_show);
1476 static struct attribute *zcache_attrs[] = {
1477 &zcache_curr_obj_count_attr.attr,
1478 &zcache_curr_obj_count_max_attr.attr,
1479 &zcache_curr_objnode_count_attr.attr,
1480 &zcache_curr_objnode_count_max_attr.attr,
1481 &zcache_flush_total_attr.attr,
1482 &zcache_flobj_total_attr.attr,
1483 &zcache_flush_found_attr.attr,
1484 &zcache_flobj_found_attr.attr,
1485 &zcache_failed_eph_puts_attr.attr,
1486 &zcache_failed_pers_puts_attr.attr,
1487 &zcache_compress_poor_attr.attr,
1488 &zcache_mean_compress_poor_attr.attr,
1489 &zcache_zbud_curr_raw_pages_attr.attr,
1490 &zcache_zbud_curr_zpages_attr.attr,
1491 &zcache_zbud_curr_zbytes_attr.attr,
1492 &zcache_zbud_cumul_zpages_attr.attr,
1493 &zcache_zbud_cumul_zbytes_attr.attr,
1494 &zcache_zbud_buddied_count_attr.attr,
1495 &zcache_zbpg_unused_list_count_attr.attr,
1496 &zcache_evicted_raw_pages_attr.attr,
1497 &zcache_evicted_unbuddied_pages_attr.attr,
1498 &zcache_evicted_buddied_pages_attr.attr,
1499 &zcache_failed_get_free_pages_attr.attr,
1500 &zcache_failed_alloc_attr.attr,
1501 &zcache_put_to_flush_attr.attr,
1502 &zcache_zbud_unbuddied_list_counts_attr.attr,
1503 &zcache_zbud_cumul_chunk_counts_attr.attr,
1504 &zcache_zv_curr_dist_counts_attr.attr,
1505 &zcache_zv_cumul_dist_counts_attr.attr,
1506 &zcache_zv_max_zsize_attr.
attr,
1507 &zcache_zv_max_mean_zsize_attr.
attr,
1508 &zcache_zv_page_count_policy_percent_attr.
attr,
1513 .
attrs = zcache_attrs,
1525 static bool zcache_freeze;
1541 zbud_evict_pages(nr);
1548 static struct shrinker zcache_shrinker = {
1549 .shrink = shrink_zcache_memory,
1567 if (!zcache_freeze && zcache_do_preload(pool) == 0) {
1569 ret =
tmem_put(pool, oidp, index, (
char *)(page),
1573 zcache_failed_eph_puts++;
1575 zcache_failed_pers_puts++;
1578 zcache_put_to_flush++;
1594 unsigned long flags;
1601 ret =
tmem_get(pool, oidp, index, (
char *)(page),
1614 unsigned long flags;
1617 zcache_flush_total++;
1625 zcache_flush_found++;
1635 unsigned long flags;
1638 zcache_flobj_total++;
1646 zcache_flobj_found++;
1651 static int zcache_destroy_pool(
int cli_id,
int pool_id)
1660 cli = get_zcache_client(cli_id);
1677 pr_info(
"zcache: destroyed pool id=%d, cli_id=%d\n",
1690 cli = get_zcache_client(cli_id);
1697 pr_info(
"zcache: pool creation failed: out of memory\n");
1705 pr_info(
"zcache: pool creation failed: out of memory\n");
1711 pr_info(
"zcache: pool creation failed: error %d\n", r);
1720 pr_info(
"zcache: created %s tmem pool, id=%d, client=%d\n",
1737 #ifdef CONFIG_CLEANCACHE
1738 static void zcache_cleancache_put_page(
int pool_id,
1740 pgoff_t index,
struct page *page)
1745 if (
likely(ind == index))
1749 static int zcache_cleancache_get_page(
int pool_id,
1751 pgoff_t index,
struct page *page)
1757 if (
likely(ind == index))
1762 static void zcache_cleancache_flush_page(
int pool_id,
1769 if (
likely(ind == index))
1773 static void zcache_cleancache_flush_inode(
int pool_id,
1781 static void zcache_cleancache_flush_fs(
int pool_id)
1787 static int zcache_cleancache_init_fs(
size_t pagesize)
1795 static int zcache_cleancache_init_shared_fs(
char *
uuid,
size_t pagesize)
1805 .
put_page = zcache_cleancache_put_page,
1806 .get_page = zcache_cleancache_get_page,
1807 .invalidate_page = zcache_cleancache_flush_page,
1808 .invalidate_inode = zcache_cleancache_flush_inode,
1809 .invalidate_fs = zcache_cleancache_flush_fs,
1810 .init_shared_fs = zcache_cleancache_init_shared_fs,
1811 .init_fs = zcache_cleancache_init_fs
1823 #ifdef CONFIG_FRONTSWAP
1825 static int zcache_frontswap_poolid = -1;
1834 #define SWIZ_MASK ((1 << SWIZ_BITS) - 1)
1835 #define _oswiz(_type, _ind) ((_type << SWIZ_BITS) | (_ind & SWIZ_MASK))
1836 #define iswiz(_ind) (_ind >> SWIZ_BITS)
1845 static int zcache_frontswap_store(
unsigned type,
pgoff_t offset,
1850 struct tmem_oid oid = oswiz(type, ind);
1852 unsigned long flags;
1854 BUG_ON(!PageLocked(page));
1855 if (
likely(ind64 == ind)) {
1858 &oid,
iswiz(ind), page);
1866 static int zcache_frontswap_load(
unsigned type,
pgoff_t offset,
1871 struct tmem_oid oid = oswiz(type, ind);
1874 BUG_ON(!PageLocked(page));
1875 if (
likely(ind64 == ind))
1877 &oid,
iswiz(ind), page);
1882 static void zcache_frontswap_flush_page(
unsigned type,
pgoff_t offset)
1886 struct tmem_oid oid = oswiz(type, ind);
1888 if (
likely(ind64 == ind))
1894 static void zcache_frontswap_flush_area(
unsigned type)
1899 for (ind =
SWIZ_MASK; ind >= 0; ind--) {
1900 oid = oswiz(type, ind);
1902 zcache_frontswap_poolid, &oid);
1906 static void zcache_frontswap_init(
unsigned ignored)
1909 if (zcache_frontswap_poolid < 0)
1910 zcache_frontswap_poolid =
1915 .
store = zcache_frontswap_store,
1916 .load = zcache_frontswap_load,
1917 .invalidate_page = zcache_frontswap_flush_page,
1918 .invalidate_area = zcache_frontswap_flush_area,
1919 .init = zcache_frontswap_init
1937 static int zcache_enabled;
1939 static int __init enable_zcache(
char *
s)
1944 __setup(
"zcache", enable_zcache);
1948 static int use_cleancache = 1;
1950 static int __init no_cleancache(
char *
s)
1956 __setup(
"nocleancache", no_cleancache);
1958 static int use_frontswap = 1;
1960 static int __init no_frontswap(
char *
s)
1966 __setup(
"nofrontswap", no_frontswap);
1968 static int __init enable_zcache_compressor(
char *
s)
1974 __setup(
"zcache=", enable_zcache_compressor);
1977 static int __init zcache_comp_init(
void)
1982 if (*zcache_comp_name !=
'\0') {
1983 ret = crypto_has_comp(zcache_comp_name, 0, 0);
1985 pr_info(
"zcache: %s not supported\n",
1989 strcpy(zcache_comp_name,
"lzo");
1990 ret = crypto_has_comp(zcache_comp_name, 0, 0);
1995 pr_info(
"zcache: using %s compressor\n", zcache_comp_name);
2000 if (!zcache_comp_pcpu_tfms)
2006 static int __init zcache_init(
void)
2013 pr_err(
"zcache: can't create sysfs\n");
2018 if (zcache_enabled) {
2023 ret = register_cpu_notifier(&zcache_cpu_notifier_block);
2025 pr_err(
"zcache: can't register cpu notifier\n");
2028 ret = zcache_comp_init();
2030 pr_err(
"zcache: compressor initialization failed\n");
2034 void *pcpu = (
void *)(
long)
cpu;
2035 zcache_cpu_notifier(&zcache_cpu_notifier_block,
2045 pr_err(
"zcache: can't create client\n");
2049 #ifdef CONFIG_CLEANCACHE
2050 if (zcache_enabled && use_cleancache) {
2056 pr_info(
"zcache: cleancache enabled using kernel "
2057 "transcendent memory and compression buddies\n");
2058 if (old_ops.init_fs !=
NULL)
2059 pr_warning(
"zcache: cleancache_ops overridden");
2062 #ifdef CONFIG_FRONTSWAP
2063 if (zcache_enabled && use_frontswap) {
2067 pr_info(
"zcache: frontswap enabled using kernel "
2068 "transcendent memory and zsmalloc\n");
2069 if (old_ops.init !=
NULL)
2070 pr_warning(
"zcache: frontswap_ops overridden");