| .. | .. |
|---|
| 18 | 18 | #include <linux/highmem.h> |
|---|
| 19 | 19 | #include <linux/slab.h> |
|---|
| 20 | 20 | #include <linux/spinlock.h> |
|---|
| 21 | | -#include <linux/local_lock.h> |
|---|
| 22 | 21 | #include <linux/types.h> |
|---|
| 23 | 22 | #include <linux/atomic.h> |
|---|
| 24 | 23 | #include <linux/frontswap.h> |
|---|
| .. | .. |
|---|
| 388 | 387 | /********************************* |
|---|
| 389 | 388 | * per-cpu code |
|---|
| 390 | 389 | **********************************/ |
|---|
| 391 | | -struct zswap_comp { |
|---|
| 392 | | - /* Used for per-CPU dstmem and tfm */ |
|---|
| 393 | | - local_lock_t lock; |
|---|
| 394 | | - u8 *dstmem; |
|---|
| 395 | | -}; |
|---|
| 396 | | - |
|---|
| 397 | | -static DEFINE_PER_CPU(struct zswap_comp, zswap_comp) = { |
|---|
| 398 | | - .lock = INIT_LOCAL_LOCK(lock), |
|---|
| 399 | | -}; |
|---|
| 390 | +static DEFINE_PER_CPU(u8 *, zswap_dstmem); |
|---|
| 400 | 391 | |
|---|
| 401 | 392 | static int zswap_dstmem_prepare(unsigned int cpu) |
|---|
| 402 | 393 | { |
|---|
| 403 | | - struct zswap_comp *zcomp; |
|---|
| 404 | 394 | u8 *dst; |
|---|
| 405 | 395 | |
|---|
| 406 | 396 | dst = kmalloc_node(PAGE_SIZE * 2, GFP_KERNEL, cpu_to_node(cpu)); |
|---|
| 407 | 397 | if (!dst) |
|---|
| 408 | 398 | return -ENOMEM; |
|---|
| 409 | 399 | |
|---|
| 410 | | - zcomp = per_cpu_ptr(&zswap_comp, cpu); |
|---|
| 411 | | - zcomp->dstmem = dst; |
|---|
| 400 | + per_cpu(zswap_dstmem, cpu) = dst; |
|---|
| 412 | 401 | return 0; |
|---|
| 413 | 402 | } |
|---|
| 414 | 403 | |
|---|
| 415 | 404 | static int zswap_dstmem_dead(unsigned int cpu) |
|---|
| 416 | 405 | { |
|---|
| 417 | | - struct zswap_comp *zcomp; |
|---|
| 406 | + u8 *dst; |
|---|
| 418 | 407 | |
|---|
| 419 | | - zcomp = per_cpu_ptr(&zswap_comp, cpu); |
|---|
| 420 | | - kfree(zcomp->dstmem); |
|---|
| 421 | | - zcomp->dstmem = NULL; |
|---|
| 408 | + dst = per_cpu(zswap_dstmem, cpu); |
|---|
| 409 | + kfree(dst); |
|---|
| 410 | + per_cpu(zswap_dstmem, cpu) = NULL; |
|---|
| 422 | 411 | |
|---|
| 423 | 412 | return 0; |
|---|
| 424 | 413 | } |
|---|
| .. | .. |
|---|
| 930 | 919 | dlen = PAGE_SIZE; |
|---|
| 931 | 920 | src = (u8 *)zhdr + sizeof(struct zswap_header); |
|---|
| 932 | 921 | dst = kmap_atomic(page); |
|---|
| 933 | | - local_lock(&zswap_comp.lock); |
|---|
| 934 | | - tfm = *this_cpu_ptr(entry->pool->tfm); |
|---|
| 922 | + tfm = *get_cpu_ptr(entry->pool->tfm); |
|---|
| 935 | 923 | ret = crypto_comp_decompress(tfm, src, entry->length, |
|---|
| 936 | 924 | dst, &dlen); |
|---|
| 937 | | - local_unlock(&zswap_comp.lock); |
|---|
| 925 | + put_cpu_ptr(entry->pool->tfm); |
|---|
| 938 | 926 | kunmap_atomic(dst); |
|---|
| 939 | 927 | BUG_ON(ret); |
|---|
| 940 | 928 | BUG_ON(dlen != PAGE_SIZE); |
|---|
| .. | .. |
|---|
| 1086 | 1074 | } |
|---|
| 1087 | 1075 | |
|---|
| 1088 | 1076 | /* compress */ |
|---|
| 1089 | | - local_lock(&zswap_comp.lock); |
|---|
| 1090 | | - dst = *this_cpu_ptr(&zswap_comp.dstmem); |
|---|
| 1091 | | - tfm = *this_cpu_ptr(entry->pool->tfm); |
|---|
| 1077 | + dst = get_cpu_var(zswap_dstmem); |
|---|
| 1078 | + tfm = *get_cpu_ptr(entry->pool->tfm); |
|---|
| 1092 | 1079 | src = kmap_atomic(page); |
|---|
| 1093 | 1080 | ret = crypto_comp_compress(tfm, src, PAGE_SIZE, dst, &dlen); |
|---|
| 1094 | 1081 | kunmap_atomic(src); |
|---|
| 1082 | + put_cpu_ptr(entry->pool->tfm); |
|---|
| 1095 | 1083 | if (ret) { |
|---|
| 1096 | 1084 | ret = -EINVAL; |
|---|
| 1097 | 1085 | goto put_dstmem; |
|---|
| .. | .. |
|---|
| 1115 | 1103 | memcpy(buf, &zhdr, hlen); |
|---|
| 1116 | 1104 | memcpy(buf + hlen, dst, dlen); |
|---|
| 1117 | 1105 | zpool_unmap_handle(entry->pool->zpool, handle); |
|---|
| 1118 | | - local_unlock(&zswap_comp.lock); |
|---|
| 1106 | + put_cpu_var(zswap_dstmem); |
|---|
| 1119 | 1107 | |
|---|
| 1120 | 1108 | /* populate entry */ |
|---|
| 1121 | 1109 | entry->offset = offset; |
|---|
| .. | .. |
|---|
| 1143 | 1131 | return 0; |
|---|
| 1144 | 1132 | |
|---|
| 1145 | 1133 | put_dstmem: |
|---|
| 1146 | | - local_unlock(&zswap_comp.lock); |
|---|
| 1134 | + put_cpu_var(zswap_dstmem); |
|---|
| 1147 | 1135 | zswap_pool_put(entry->pool); |
|---|
| 1148 | 1136 | freepage: |
|---|
| 1149 | 1137 | zswap_entry_cache_free(entry); |
|---|
| .. | .. |
|---|
| 1188 | 1176 | if (zpool_evictable(entry->pool->zpool)) |
|---|
| 1189 | 1177 | src += sizeof(struct zswap_header); |
|---|
| 1190 | 1178 | dst = kmap_atomic(page); |
|---|
| 1191 | | - local_lock(&zswap_comp.lock); |
|---|
| 1192 | | - tfm = *this_cpu_ptr(entry->pool->tfm); |
|---|
| 1179 | + tfm = *get_cpu_ptr(entry->pool->tfm); |
|---|
| 1193 | 1180 | ret = crypto_comp_decompress(tfm, src, entry->length, dst, &dlen); |
|---|
| 1194 | | - local_unlock(&zswap_comp.lock); |
|---|
| 1181 | + put_cpu_ptr(entry->pool->tfm); |
|---|
| 1195 | 1182 | kunmap_atomic(dst); |
|---|
| 1196 | 1183 | zpool_unmap_handle(entry->pool->zpool, entry->handle); |
|---|
| 1197 | 1184 | BUG_ON(ret); |
|---|