Commit a7a03505 authored by Sergey Senozhatsky's avatar Sergey Senozhatsky Committed by Andrew Morton

zram: split memory-tracking and ac-time tracking

ZRAM_MEMORY_TRACKING enables two features:
- per-entry ac-time tracking
- debugfs interface

The latter one is the reason why memory-tracking depends on DEBUG_FS,
while the former one is used far beyond debugging these days.  Namely
ac-time is used for fine grained writeback of idle entries (pages).

Move ac-time tracking under its own config option so that it can be
enabled (along with writeback) on systems without DEBUG_FS.

[senozhatsky@chromium.org: ifdef fixup, per Dmytro]
  Link: https://lkml.kernel.org/r/20231117013543.540280-1-senozhatsky@chromium.org
Link: https://lkml.kernel.org/r/20231115024223.4133148-1-senozhatsky@chromium.orgSigned-off-by: default avatarSergey Senozhatsky <senozhatsky@chromium.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Dmytro Maluka <dmaluka@chromium.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 1b5c65b6
...@@ -328,7 +328,7 @@ as idle:: ...@@ -328,7 +328,7 @@ as idle::
From now on, any pages on zram are idle pages. The idle mark From now on, any pages on zram are idle pages. The idle mark
will be removed until someone requests access of the block. will be removed until someone requests access of the block.
IOW, unless there is access request, those pages are still idle pages. IOW, unless there is access request, those pages are still idle pages.
Additionally, when CONFIG_ZRAM_MEMORY_TRACKING is enabled pages can be Additionally, when CONFIG_ZRAM_TRACK_ENTRY_ACTIME is enabled pages can be
marked as idle based on how long (in seconds) it's been since they were marked as idle based on how long (in seconds) it's been since they were
last accessed:: last accessed::
......
...@@ -69,9 +69,18 @@ config ZRAM_WRITEBACK ...@@ -69,9 +69,18 @@ config ZRAM_WRITEBACK
See Documentation/admin-guide/blockdev/zram.rst for more information. See Documentation/admin-guide/blockdev/zram.rst for more information.
config ZRAM_TRACK_ENTRY_ACTIME
bool "Track access time of zram entries"
depends on ZRAM
help
With this feature zram tracks access time of every stored
entry (page), which can be used for a more fine grained IDLE
pages writeback.
config ZRAM_MEMORY_TRACKING config ZRAM_MEMORY_TRACKING
bool "Track zRam block status" bool "Track zRam block status"
depends on ZRAM && DEBUG_FS depends on ZRAM && DEBUG_FS
select ZRAM_TRACK_ENTRY_ACTIME
help help
With this feature, admin can track the state of allocated blocks With this feature, admin can track the state of allocated blocks
of zRAM. Admin could see the information via of zRAM. Admin could see the information via
...@@ -86,4 +95,4 @@ config ZRAM_MULTI_COMP ...@@ -86,4 +95,4 @@ config ZRAM_MULTI_COMP
This will enable multi-compression streams, so that ZRAM can This will enable multi-compression streams, so that ZRAM can
re-compress pages using a potentially slower but more effective re-compress pages using a potentially slower but more effective
compression algorithm. Note, that IDLE page recompression compression algorithm. Note, that IDLE page recompression
requires ZRAM_MEMORY_TRACKING. requires ZRAM_TRACK_ENTRY_ACTIME.
...@@ -174,6 +174,14 @@ static inline u32 zram_get_priority(struct zram *zram, u32 index) ...@@ -174,6 +174,14 @@ static inline u32 zram_get_priority(struct zram *zram, u32 index)
return prio & ZRAM_COMP_PRIORITY_MASK; return prio & ZRAM_COMP_PRIORITY_MASK;
} }
static void zram_accessed(struct zram *zram, u32 index)
{
zram_clear_flag(zram, index, ZRAM_IDLE);
#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME
zram->table[index].ac_time = ktime_get_boottime();
#endif
}
static inline void update_used_max(struct zram *zram, static inline void update_used_max(struct zram *zram,
const unsigned long pages) const unsigned long pages)
{ {
...@@ -293,8 +301,9 @@ static void mark_idle(struct zram *zram, ktime_t cutoff) ...@@ -293,8 +301,9 @@ static void mark_idle(struct zram *zram, ktime_t cutoff)
zram_slot_lock(zram, index); zram_slot_lock(zram, index);
if (zram_allocated(zram, index) && if (zram_allocated(zram, index) &&
!zram_test_flag(zram, index, ZRAM_UNDER_WB)) { !zram_test_flag(zram, index, ZRAM_UNDER_WB)) {
#ifdef CONFIG_ZRAM_MEMORY_TRACKING #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME
is_idle = !cutoff || ktime_after(cutoff, zram->table[index].ac_time); is_idle = !cutoff || ktime_after(cutoff,
zram->table[index].ac_time);
#endif #endif
if (is_idle) if (is_idle)
zram_set_flag(zram, index, ZRAM_IDLE); zram_set_flag(zram, index, ZRAM_IDLE);
...@@ -317,7 +326,7 @@ static ssize_t idle_store(struct device *dev, ...@@ -317,7 +326,7 @@ static ssize_t idle_store(struct device *dev,
*/ */
u64 age_sec; u64 age_sec;
if (IS_ENABLED(CONFIG_ZRAM_MEMORY_TRACKING) && !kstrtoull(buf, 0, &age_sec)) if (IS_ENABLED(CONFIG_ZRAM_TRACK_ENTRY_ACTIME) && !kstrtoull(buf, 0, &age_sec))
cutoff_time = ktime_sub(ktime_get_boottime(), cutoff_time = ktime_sub(ktime_get_boottime(),
ns_to_ktime(age_sec * NSEC_PER_SEC)); ns_to_ktime(age_sec * NSEC_PER_SEC));
else else
...@@ -841,12 +850,6 @@ static void zram_debugfs_destroy(void) ...@@ -841,12 +850,6 @@ static void zram_debugfs_destroy(void)
debugfs_remove_recursive(zram_debugfs_root); debugfs_remove_recursive(zram_debugfs_root);
} }
static void zram_accessed(struct zram *zram, u32 index)
{
zram_clear_flag(zram, index, ZRAM_IDLE);
zram->table[index].ac_time = ktime_get_boottime();
}
static ssize_t read_block_state(struct file *file, char __user *buf, static ssize_t read_block_state(struct file *file, char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
...@@ -930,10 +933,6 @@ static void zram_debugfs_unregister(struct zram *zram) ...@@ -930,10 +933,6 @@ static void zram_debugfs_unregister(struct zram *zram)
#else #else
static void zram_debugfs_create(void) {}; static void zram_debugfs_create(void) {};
static void zram_debugfs_destroy(void) {}; static void zram_debugfs_destroy(void) {};
static void zram_accessed(struct zram *zram, u32 index)
{
zram_clear_flag(zram, index, ZRAM_IDLE);
};
static void zram_debugfs_register(struct zram *zram) {}; static void zram_debugfs_register(struct zram *zram) {};
static void zram_debugfs_unregister(struct zram *zram) {}; static void zram_debugfs_unregister(struct zram *zram) {};
#endif #endif
...@@ -1254,7 +1253,7 @@ static void zram_free_page(struct zram *zram, size_t index) ...@@ -1254,7 +1253,7 @@ static void zram_free_page(struct zram *zram, size_t index)
{ {
unsigned long handle; unsigned long handle;
#ifdef CONFIG_ZRAM_MEMORY_TRACKING #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME
zram->table[index].ac_time = 0; zram->table[index].ac_time = 0;
#endif #endif
if (zram_test_flag(zram, index, ZRAM_IDLE)) if (zram_test_flag(zram, index, ZRAM_IDLE))
......
...@@ -69,7 +69,7 @@ struct zram_table_entry { ...@@ -69,7 +69,7 @@ struct zram_table_entry {
unsigned long element; unsigned long element;
}; };
unsigned long flags; unsigned long flags;
#ifdef CONFIG_ZRAM_MEMORY_TRACKING #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME
ktime_t ac_time; ktime_t ac_time;
#endif #endif
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment