hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAFWQH ---------------------------------------- Prepare to support multiple pool. Currently, only zspool 0 is used. Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com> --- .../multi_pool_zram/multi_pool_zram_drv.c | 72 +++++++++++++++---- .../multi_pool_zram/multi_pool_zram_drv.h | 14 +++- 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/drivers/block/multi_pool_zram/multi_pool_zram_drv.c b/drivers/block/multi_pool_zram/multi_pool_zram_drv.c index 987dadebaf07..a5f8a7ba799e 100644 --- a/drivers/block/multi_pool_zram/multi_pool_zram_drv.c +++ b/drivers/block/multi_pool_zram/multi_pool_zram_drv.c @@ -78,6 +78,18 @@ static void zram_set_handle(struct zram *zram, u32 index, unsigned long handle) zram->table[index].handle = handle; } +static struct zs_pool *zram_get_pool(struct zram *zram, u32 index) +{ + int pool_index = zram->table[index].pool_index; + + return zram->mem_pool[pool_index]; +} + +static void zram_set_pool_index(struct zram *zram, u32 index, int pool_index) +{ + zram->table[index].pool_index = pool_index; +} + /* flag operations require table entry bit_spin_lock() being held */ static bool zram_test_flag(struct zram *zram, u32 index, enum zram_pageflags flag) @@ -265,6 +277,31 @@ static ssize_t debug_stat_show(struct device *dev, return ret; } +static void zram_pool_destroy(struct zram *zram) +{ + int i; + + for (i = 0; i < NR_ZPOOL; ++i) + if (zram->mem_pool[i]) + zs_destroy_pool(zram->mem_pool[i]); +} + +static int zram_pool_create(struct zram *zram) +{ + char name[64]; + int i; + + for (i = 0; i < NR_ZPOOL; ++i) { + snprintf(name, 64, "%s-%d", zram->disk->disk_name, i); + zram->mem_pool[i] = zs_create_pool(name); + if (!zram->mem_pool[i]) { + zram_pool_destroy(zram); + return -ENOMEM; + } + } + + return 0; +} static DEVICE_ATTR_RO(io_stat); static DEVICE_ATTR_RO(debug_stat); @@ -281,7 +318,7 @@ static void zram_meta_free(struct zram *zram, u64 disksize) for (index = 0; index < num_pages; index++) zram_free_page(zram, index); - zs_destroy_pool(zram->mem_pool); + zram_pool_destroy(zram); vfree(zram->table); zram->table = NULL; } @@ -290,20 +327,21 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) { size_t num_pages = disksize >> PAGE_SHIFT; unsigned long size = array_size(num_pages, sizeof(*zram->table)); + int ret; zram->table = vzalloc(size); if (!zram->table) return false; - zram->mem_pool = zs_create_pool(zram->disk->disk_name); - if (!zram->mem_pool) { + ret = zram_pool_create(zram); + if (ret) { vfree(zram->table); zram->table = NULL; return false; } if (!huge_class_size) - huge_class_size = zs_huge_class_size(zram->mem_pool); + huge_class_size = zs_huge_class_size(zram->mem_pool[DEFAULT_ZPOOL_INDEX]); return true; } @@ -315,6 +353,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize) static void zram_free_page(struct zram *zram, size_t index) { unsigned long handle; + struct zs_pool *pool; if (zram_test_flag(zram, index, ZRAM_HUGE)) { zram_clear_flag(zram, index, ZRAM_HUGE); @@ -335,13 +374,15 @@ static void zram_free_page(struct zram *zram, size_t index) if (!handle) return; - zs_free(zram->mem_pool, handle); + pool = zram_get_pool(zram, index); + zs_free(pool, handle); atomic64_sub(zram_get_obj_size(zram, index), &zram->stats.compr_data_size); out: atomic64_dec(&zram->stats.pages_stored); zram_set_handle(zram, index, 0); + zram_set_pool_index(zram, index, DEFAULT_ZPOOL_INDEX); zram_set_obj_size(zram, index, 0); WARN_ON_ONCE(zram->table[index].flags & ~(1UL << ZRAM_LOCK)); @@ -355,6 +396,7 @@ static int zram_read_from_zspool(struct zram *zram, struct page *page, u32 index) { struct zcomp_strm *zstrm; + struct zs_pool *pool; unsigned long handle; unsigned int size; void *src, *dst; @@ -372,12 +414,13 @@ static int zram_read_from_zspool(struct zram *zram, struct page *page, return 0; } + pool = zram_get_pool(zram, index); size = zram_get_obj_size(zram, index); if (size != PAGE_SIZE) zstrm = zcomp_stream_get(zram->comp); - src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); + src = zs_map_object(pool, handle, ZS_MM_RO); if (size == PAGE_SIZE) { dst = kmap_atomic(page); memcpy(dst, src, PAGE_SIZE); @@ -389,7 +432,7 @@ static int zram_read_from_zspool(struct zram *zram, struct page *page, kunmap_atomic(dst); zcomp_stream_put(zram->comp); } - zs_unmap_object(zram->mem_pool, handle); + zs_unmap_object(pool, handle); return ret; } @@ -446,6 +489,8 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) struct zcomp_strm *zstrm; unsigned long element = 0; enum zram_pageflags flags = 0; + struct zs_pool *pool; + int pool_index; mem = kmap_atomic(page); if (page_same_filled(mem, &element)) { @@ -457,6 +502,8 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) } kunmap_atomic(mem); + pool_index = DEFAULT_ZPOOL_INDEX; + pool = zram->mem_pool[pool_index]; compress_again: zstrm = zcomp_stream_get(zram->comp); src = kmap_atomic(page); @@ -466,7 +513,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) if (unlikely(ret)) { zcomp_stream_put(zram->comp); pr_err("Compression failed! err=%d\n", ret); - zs_free(zram->mem_pool, handle); + zs_free(pool, handle); return ret; } @@ -486,7 +533,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) * from the slow path and handle has already been allocated. */ if (IS_ERR_VALUE(handle)) - handle = zs_malloc(zram->mem_pool, comp_len, + handle = zs_malloc(pool, comp_len, __GFP_KSWAPD_RECLAIM | __GFP_NOWARN | __GFP_HIGHMEM | @@ -494,7 +541,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) if (IS_ERR_VALUE(handle)) { zcomp_stream_put(zram->comp); atomic64_inc(&zram->stats.writestall); - handle = zs_malloc(zram->mem_pool, comp_len, + handle = zs_malloc(pool, comp_len, GFP_NOIO | __GFP_HIGHMEM | __GFP_MOVABLE); if (IS_ERR_VALUE(handle)) @@ -512,7 +559,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) zstrm = zcomp_stream_get(zram->comp); } - dst = zs_map_object(zram->mem_pool, handle, ZS_MM_WO); + dst = zs_map_object(pool, handle, ZS_MM_WO); src = zstrm->buffer; if (comp_len == PAGE_SIZE) src = kmap_atomic(page); @@ -521,7 +568,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) kunmap_atomic(src); zcomp_stream_put(zram->comp); - zs_unmap_object(zram->mem_pool, handle); + zs_unmap_object(pool, handle); atomic64_add(comp_len, &zram->stats.compr_data_size); out: /* @@ -542,6 +589,7 @@ static int zram_write_page(struct zram *zram, struct page *page, u32 index) zram_set_element(zram, index, element); } else { zram_set_handle(zram, index, handle); + zram_set_pool_index(zram, index, pool_index); zram_set_obj_size(zram, index, comp_len); } zram_slot_unlock(zram, index); diff --git a/drivers/block/multi_pool_zram/multi_pool_zram_drv.h b/drivers/block/multi_pool_zram/multi_pool_zram_drv.h index 7d96139a94df..0304149b1697 100644 --- a/drivers/block/multi_pool_zram/multi_pool_zram_drv.h +++ b/drivers/block/multi_pool_zram/multi_pool_zram_drv.h @@ -20,6 +20,17 @@ #define ZRAM_SECTOR_PER_LOGICAL_BLOCK \ (1 << (ZRAM_LOGICAL_BLOCK_SHIFT - SECTOR_SHIFT)) +/* + * the 1~256 zpools can be bounded to memcgs. The memory + * allocated by the zspool will be charged to be bounded + * memcg, and IO from the memcg will use the corresponding + * zspool. + * + * The first pool is used if write IO isn't bounded to memcg + * or the memcg isn't bounded to any zpool. + */ +#define NR_ZPOOL 257 +#define DEFAULT_ZPOOL_INDEX 0 /* * ZRAM is mainly used for memory efficiency so we want to keep memory @@ -50,6 +61,7 @@ struct zram_table_entry { unsigned long handle; unsigned long element; }; + int pool_index; unsigned long flags; }; @@ -67,7 +79,7 @@ struct zram_stats { struct zram { struct zram_table_entry *table; - struct zs_pool *mem_pool; + struct zs_pool *mem_pool[NR_ZPOOL]; struct zcomp *comp; struct gendisk *disk; /* Prevent concurrent execution of device init */ -- 2.43.0