|
65 | 65 | #include <linux/wait.h>
|
66 | 66 | #include <linux/pagemap.h>
|
67 | 67 | #include <linux/fs.h>
|
| 68 | +#include <linux/local_lock.h> |
68 | 69 |
|
69 | 70 | #define ZSPAGE_MAGIC 0x58
|
70 | 71 |
|
@@ -276,6 +277,7 @@ struct zspage {
|
276 | 277 | };
|
277 | 278 |
|
278 | 279 | struct mapping_area {
|
| 280 | + local_lock_t lock; |
279 | 281 | char *vm_buf; /* copy buffer for objects that span pages */
|
280 | 282 | char *vm_addr; /* address of kmap_atomic()'ed pages */
|
281 | 283 | enum zs_mapmode vm_mm; /* mapping mode */
|
@@ -451,7 +453,9 @@ MODULE_ALIAS("zpool-zsmalloc");
|
451 | 453 | #endif /* CONFIG_ZPOOL */
|
452 | 454 |
|
453 | 455 | /* per-cpu VM mapping areas for zspage accesses that cross page boundaries */
|
454 |
| -static DEFINE_PER_CPU(struct mapping_area, zs_map_area); |
| 456 | +static DEFINE_PER_CPU(struct mapping_area, zs_map_area) = { |
| 457 | + .lock = INIT_LOCAL_LOCK(lock), |
| 458 | +}; |
455 | 459 |
|
456 | 460 | static __maybe_unused int is_first_page(struct page *page)
|
457 | 461 | {
|
@@ -1269,7 +1273,8 @@ void *zs_map_object(struct zs_pool *pool, unsigned long handle,
|
1269 | 1273 | class = zspage_class(pool, zspage);
|
1270 | 1274 | off = (class->size * obj_idx) & ~PAGE_MASK;
|
1271 | 1275 |
|
1272 |
| - area = &get_cpu_var(zs_map_area); |
| 1276 | + local_lock(&zs_map_area.lock); |
| 1277 | + area = this_cpu_ptr(&zs_map_area); |
1273 | 1278 | area->vm_mm = mm;
|
1274 | 1279 | if (off + class->size <= PAGE_SIZE) {
|
1275 | 1280 | /* this object is contained entirely within a page */
|
@@ -1320,7 +1325,7 @@ void zs_unmap_object(struct zs_pool *pool, unsigned long handle)
|
1320 | 1325 |
|
1321 | 1326 | __zs_unmap_object(area, pages, off, class->size);
|
1322 | 1327 | }
|
1323 |
| - put_cpu_var(zs_map_area); |
| 1328 | + local_unlock(&zs_map_area.lock); |
1324 | 1329 |
|
1325 | 1330 | migrate_read_unlock(zspage);
|
1326 | 1331 | }
|
|
0 commit comments