--- zzzz-none-000/linux-4.4.60/drivers/block/zram/zram_drv.c 2017-04-08 07:53:53.000000000 +0000 +++ scorpion-7490-727/linux-4.4.60/drivers/block/zram/zram_drv.c 2021-02-04 17:41:59.000000000 +0000 @@ -30,6 +30,7 @@ #include #include #include +#include #include "zram_drv.h" @@ -1184,6 +1185,44 @@ .attrs = zram_disk_attrs, }; +static int oom_info_callback(struct notifier_block *block, unsigned long event, void *_data) +{ + struct zram *zram = container_of(block, struct zram, oom_info_block); + struct avm_oom_info_data *data = _data; + struct zs_pool_stats pool_stats; + u64 orig_size, mem_used = 0; + long max_used; + + memset(&pool_stats, 0x00, sizeof(struct zs_pool_stats)); + + // Unlik mm_stat we don't use semaphores to lock the access here. This is needed as the + // info_callback is called in an atomic context. + // + // All of the calls made here are either normal reads or atomic reads. Which can be done + // unguarded. The worst is, that we get inconsistent data, which should be easily detectable + // by inspecting the output. + if (init_done(zram)) { + mem_used = zs_get_total_pages(zram->meta->mem_pool); + zs_pool_stats(zram->meta->mem_pool, &pool_stats); + } + + orig_size = atomic64_read(&zram->stats.pages_stored); + max_used = atomic_long_read(&zram->stats.max_used_pages); + + data->printf(data, + "%s: orig:%lluKiB compr:%lluKiB used:%lluKiB limit:%luKiB max:%ldKiB zero:%llu compact:%lu\n", + zram->disk->disk_name, + orig_size << (PAGE_SHIFT - 10), + (u64)atomic64_read(&zram->stats.compr_data_size) >> 10, + mem_used << (PAGE_SHIFT - 10), + zram->limit_pages << (PAGE_SHIFT - 10), + max_used << (PAGE_SHIFT - 10), + (u64)atomic64_read(&zram->stats.zero_pages), + pool_stats.pages_compacted); + + return NOTIFY_DONE; +} + /* * Allocate and initialize new zram device. the function returns * '>= 0' device_id upon success, and negative value otherwise. @@ -1275,6 +1314,9 @@ zram->meta = NULL; zram->max_comp_streams = 1; + zram->oom_info_block.notifier_call = oom_info_callback; + avm_oom_info_chain_register(&zram->oom_info_block); + pr_info("Added device: %s\n", zram->disk->disk_name); return device_id; @@ -1308,6 +1350,8 @@ zram->claim = true; mutex_unlock(&bdev->bd_mutex); + avm_oom_info_chain_unregister(&zram->oom_info_block); + /* * Remove sysfs first, so no one will perform a disksize * store while we destroy the devices. This also helps during