+ zram-use-u32-for-entry-ac_time-tracking.patch added to mm-new branch
Subsystems (3)
The patch titled
Subject: zram: use u32 for entry ac_time tracking
has been added to the -mm mm-new branch. Its filename is
zram-use-u32-for-entry-ac_time-tracking.patch
This patch will shortly appear at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/zram-use-u32-for-entry-ac_time-tracking.patch
This patch will later appear in the mm-new branch at
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
Note, mm-new is a provisional staging ground for work-in-progress patches, and acceptance into mm-new is a notification for others take notice and to finish up reviews. Please do not hesitate to respond to review feedback and post updated versions to replace or incrementally fixup patches in mm-new.
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next via the mm-everything branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days
------------------------------------------------------
From: Sergey Senozhatsky <[email protected]>
Subject: zram: use u32 for entry ac_time tracking
Date: Mon, 15 Dec 2025 14:47:11 +0900
We can reduce sizeof(zram_table_entry) on 64-bit systems by converting flags and ac_time to u32. Entry flags fit into u32, and for ac_time u32 gives us over a century of entry lifespan (approx 136 years) which is plenty (zram uses system boot time (seconds)).
In struct zram_table_entry we use bytes aliasing, because bit-wait API (for slot lock) requires a whole unsigned long word.
---
drivers/block/zram/zram_drv.c | 60 ++++++++++++++++---------------- drivers/block/zram/zram_drv.h | 9 +++- 2 files changed, 37 insertions(+), 32 deletions(-)
drivers/block/zram/zram_drv.c renamed from drivers/block/zram/zram_drv.c~zram-use-u32-for-entry-ac_time-tracking +30 -30
@@ -81,7 +81,7 @@ static void zram_slot_lock_init(struct z*/ static __must_check bool zram_slot_trylock (struct zram *zram,u32 index) { -unsigned long *lock = &zram->table[index].flags; +unsigned long *lock = &zram->table[index].__lock;if (!test_and_set_bit_lock (ZRAM_ENTRY_LOCK , lock)) {mutex_acquire (slot_dep_map (zram, index),0 ,1 , _RET_IP_);
@@ -94,7 +94,7 @@ static __must_check bool zram_slot_trylostatic void zram_slot_lock (struct zram *zram,u32 index) { -unsigned long *lock = &zram->table[index].flags; +unsigned long *lock = &zram->table[index].__lock;mutex_acquire (slot_dep_map (zram, index),0 ,0 , _RET_IP_);wait_on_bit_lock (lock,ZRAM_ENTRY_LOCK ,TASK_UNINTERRUPTIBLE );
@@ -103,7 +103,7 @@ static void zram_slot_lock(struct zram *static void zram_slot_unlock (struct zram *zram,u32 index) { -unsigned long *lock = &zram->table[index].flags; +unsigned long *lock = &zram->table[index].__lock;mutex_release (slot_dep_map (zram, index), _RET_IP_);clear_and_wake_up_bit (ZRAM_ENTRY_LOCK , lock);
@@ -130,34 +130,33 @@ static void zram_set_handle(struct zram }static bool zram_test_flag (struct zram *zram,u32 index, -enum zram_pageflags flag) +enum zram_pageflags flag) { -return zram->table[index].flags &BIT (flag); +return zram->table[index].attr.flags &BIT (flag); }static void zram_set_flag (struct zram *zram,u32 index, -enum zram_pageflags flag) +enum zram_pageflags flag) { - zram->table[index].flags |=BIT (flag); + zram->table[index].attr.flags |=BIT (flag); }static void zram_clear_flag (struct zram *zram,u32 index, -enum zram_pageflags flag) +enum zram_pageflags flag) { - zram->table[index].flags &= ~BIT (flag); + zram->table[index].attr.flags &= ~BIT (flag); }static size_t zram_get_obj_size (struct zram *zram,u32 index) { -return zram->table[index].flags & (BIT (ZRAM_FLAG_SHIFT ) -1 ); +return zram->table[index].attr.flags & (BIT (ZRAM_FLAG_SHIFT ) -1 ); } -static void zram_set_obj_size (struct zram *zram, -u32 index,size_t size) +static void zram_set_obj_size (struct zram *zram,u32 index,size_t size) { -unsigned long flags = zram->table[index].flags >>ZRAM_FLAG_SHIFT ; +unsigned long flags = zram->table[index].attr.flags >>ZRAM_FLAG_SHIFT ; - zram->table[index].flags = (flags <<ZRAM_FLAG_SHIFT ) | size; + zram->table[index].attr.flags = (flags <<ZRAM_FLAG_SHIFT ) | size; }static inline bool zram_allocated (struct zram *zram,u32 index)
@@ -208,14 +207,14 @@ static inline void zram_set_priority(str* Clear previous priority value first, in case if we recompress * further an already recompressed page */ - zram->table[index].flags &= ~(ZRAM_COMP_PRIORITY_MASK << -ZRAM_COMP_PRIORITY_BIT1 ); - zram->table[index].flags |= (prio <<ZRAM_COMP_PRIORITY_BIT1 ); + zram->table[index].attr.flags &= ~(ZRAM_COMP_PRIORITY_MASK << +ZRAM_COMP_PRIORITY_BIT1 ); + zram->table[index].attr.flags |= (prio <<ZRAM_COMP_PRIORITY_BIT1 ); }static inline u32 zram_get_priority (struct zram *zram,u32 index) { -u32 prio = zram->table[index].flags >>ZRAM_COMP_PRIORITY_BIT1 ; +u32 prio = zram->table[index].attr.flags >>ZRAM_COMP_PRIORITY_BIT1 ;return prio &ZRAM_COMP_PRIORITY_MASK ; }
@@ -225,7 +224,7 @@ static void zram_accessed(struct zram *zzram_clear_flag (zram, index,ZRAM_IDLE );zram_clear_flag (zram, index,ZRAM_PP_SLOT );#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME - zram->table[index].ac_time =ktime_get_boottime (); + zram->table[index].attr.ac_time = (u32 )ktime_get_boottime_seconds ();#endif }
@@ -447,7 +446,7 @@ static void mark_idle(struct zram *zram,#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME is_idle = !cutoff || -ktime_after (cutoff, zram->table[index].ac_time); +ktime_after (cutoff, zram->table[index].attr.ac_time);#endif if (is_idle)zram_set_flag (zram, index,ZRAM_IDLE );
@@ -461,18 +460,19 @@ static ssize_t idle_store(struct device const char *buf, size_t len) { struct zram *zram = dev_to_zram(dev); -ktime_t cutoff_time =0 ; +ktime_t cutoff =0 ;if (!sysfs_streq (buf,"all" )) {/* * If it did not parse as 'all' try to treat it as an integer * when we have memory tracking enabled. */ -u64 age_sec; +u32 age_sec; -if (IS_ENABLED (CONFIG_ZRAM_TRACK_ENTRY_ACTIME ) && !kstrtoull (buf,0 , &age_sec)) - cutoff_time =ktime_sub (ktime_get_boottime (), -ns_to_ktime (age_sec *NSEC_PER_SEC )); +if (IS_ENABLED (CONFIG_ZRAM_TRACK_ENTRY_ACTIME ) && + !kstrtouint (buf,0 , &age_sec)) + cutoff =ktime_sub ((u32 )ktime_get_boottime_seconds (), + age_sec);else return -EINVAL ; }
@@ -482,10 +482,10 @@ static ssize_t idle_store(struct devicereturn -EINVAL ;/* -* A cutoff_time of 0 marks everything as idle, this is the +* A cutoff of 0 marks everything as idle, this is the * "all" behavior. */ -mark_idle (zram, cutoff_time); +mark_idle (zram, cutoff);return len; }
@@ -1588,7 +1588,7 @@ static ssize_t read_block_state(struct fif (!zram_allocated (zram, index)) goto next; - ts =ktime_to_timespec64 (zram->table[index].ac_time); + ts =ktime_to_timespec64 (zram->table[index].attr.ac_time); copied = snprintf(kbuf + written, count, "%12zd %12lld.%06lu %c%c%c%c%c%c\n", index, (s64)ts.tv_sec,
@@ -2013,7 +2013,7 @@ static void zram_slot_free(struct zram *unsigned long handle;#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME - zram->table[index].ac_time =0 ; + zram->table[index].attr.ac_time =0 ;#endif zram_clear_flag (zram, index,ZRAM_IDLE );
@@ -3286,7 +3286,7 @@ static int __init zram_init(void)struct zram_table_entry zram_te;int ret; -BUILD_BUG_ON (__NR_ZRAM_PAGEFLAGS >sizeof (zram_te.flags) *8 ); +BUILD_BUG_ON (__NR_ZRAM_PAGEFLAGS >sizeof (zram_te.attr.flags) *8 ); ret =cpuhp_setup_state_multi (CPUHP_ZCOMP_PREPARE ,"block/zram:prepare" , zcomp_cpu_up_prepare, zcomp_cpu_dead);
drivers/block/zram/zram_drv.h renamed from drivers/block/zram/zram_drv.h~zram-use-u32-for-entry-ac_time-tracking +7 -2
@@ -65,10 +65,15 @@ enum zram_pageflags {*/ struct zram_table_entry {unsigned long handle; -unsigned long flags; +union { +unsigned long __lock; +struct attr { +u32 flags;#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME -ktime_t ac_time; +u32 ac_time;#endif + } attr; + };struct lockdep_map dep_map; };
_
Patches currently in -mm which might be from [email protected] are
zram-document-writeback_batch_size.patch zram-move-bd_stat-to-writeback-section.patch zram-rename-zram_free_page.patch zram-switch-to-guard-for-init_lock.patch zram-consolidate-device-attr-declarations.patch zram-use-u32-for-entry-ac_time-tracking.patch zram-rename-internal-slot-api.patch zram-trivial-fix-of-recompress_slot-coding-styles.patch
Sergey Senozhatsky
maintainerOn (25/12/15 18:27), Andrew Morton wrote:
[..]
Quoted 8 lines
static inline u32
zram_get_priority(struct zram *zram, u32 index){drivers/block/zram/zram_drv.c renamed from drivers/block/zram/zram_drv.c~zram-use-u32-for-entry-ac_time-tracking +1
-1-u32 prio = zram->table[index].flags >>ZRAM_COMP_PRIORITY_BIT1 ; +u32 prio = zram->table[index].attr.flags >>ZRAM_COMP_PRIORITY_BIT1 ;return prio &ZRAM_COMP_PRIORITY_MASK ; }
drivers/block/zram/zram_drv.c static void zram_accessed(struct zram *z · line 229
Quoted 7 lines
drivers/block/zram/zram_drv.c renamed from drivers/block/zram/zram_drv.c~zram-use-u32-for-entry-ac_time-tracking +1
-1@@ -225,7 +224,7 @@ static void zram_accessed(struct zram *zzram_clear_flag (zram, index,ZRAM_IDLE );zram_clear_flag (zram, index,ZRAM_PP_SLOT );#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME - zram->table[index].ac_time =ktime_get_boottime (); + zram->table[index].attr.ac_time = (u32 )ktime_get_boottime_seconds ();#endif }
Andrew, I sent a fixup patch for the previous patch in that series [1]. This chunk is not needed anymore, as this get_boottime conversion simply should have never happened in the first place.
Apologies for inconvenience.
Sergey Senozhatsky
maintainerQuoted 31 lines · Sergey Senozhatsky
Date: Thu, 15 Jan 2026 12:25:39 +0900
From: Sergey Senozhatsky <[email protected]>
To: Andrew Morton <[email protected]>
Cc: [email protected], [email protected], [email protected],
[email protected], [email protected], [email protected]
Subject: Re: + zram-use-u32-for-entry-ac_time-tracking.patch added to
mm-new branch
Message-ID: <aajymtsa6wesyjvh73uacvm76mi3qhn3nzqrtie3xu67y2sevx@5ntik7xg5n7d>On (25/12/15 18:27), Andrew Morton wrote:
[..]Quoted 8 lines
static inline u32
zram_get_priority(struct zram *zram, u32 index){drivers/block/zram/zram_drv.c renamed from drivers/block/zram/zram_drv.c~zram-use-u32-for-entry-ac_time-tracking +1
-1-u32 prio = zram->table[index].flags >>ZRAM_COMP_PRIORITY_BIT1 ; +u32 prio = zram->table[index].attr.flags >>ZRAM_COMP_PRIORITY_BIT1 ;return prio &ZRAM_COMP_PRIORITY_MASK ; }drivers/block/zram/zram_drv.c static void zram_accessed(struct zram *z · line 229
Quoted 7 lines
drivers/block/zram/zram_drv.c renamed from drivers/block/zram/zram_drv.c~zram-use-u32-for-entry-ac_time-tracking +1
-1@@ -225,7 +224,7 @@ static void zram_accessed(struct zram *zzram_clear_flag (zram, index,ZRAM_IDLE );zram_clear_flag (zram, index,ZRAM_PP_SLOT );#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME - zram->table[index].ac_time =ktime_get_boottime (); + zram->table[index].attr.ac_time = (u32 )ktime_get_boottime_seconds ();#endif }Andrew, I sent a fixup patch for the previous patch in that series [1]. This chunk is not needed anymore, as this
get_boottimeconversion simply should have never happened in the first place.
Quoted 3 lines
Apologies for inconvenience.
Oh, no... Please ignore this email.
It's the other way around: this patch is correct.
Sergey Senozhatsky
maintainerPATCH 2/2 zram: fixup read_block_state()
In reply to Andrew Mortonac_time is now in seconds, do not use ktime_to_timespec64()
--- drivers/block/zram/zram_drv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/block/zram/zram_drv.c +2 -4
@@ -1579,11 +1579,9 @@ static ssize_t read_block_state(struct file *file, char __user *buf,if (!slot_allocated (zram, index)) goto next; - ts =ktime_to_timespec64 (zram->table[index].attr.ac_time); copied = snprintf(kbuf + written, count, - "%12zd %12lld.%06lu %c%c%c%c%c%c\n", - index, (s64)ts.tv_sec, - ts.tv_nsec / NSEC_PER_USEC, + "%12zd %12u.%06lu %c%c%c%c%c%c\n", + index, zram->table[index].attr.ac_time, 0, test_slot_flag(zram, index, ZRAM_SAME) ? 's' : '.', test_slot_flag(zram, index, ZRAM_WB) ? 'w' : '.', test_slot_flag(zram, index, ZRAM_HUGE) ? 'h' : '.',
Signature · 1 line
2.52.0.457.g6b5491de43-goog
Andrew Morton
maintainerRe: [PATCH 2/2] zram: fixup read_block_state()
Quoted 1 line · On Thu, 15 Jan 2026 12:30:06 +0900 Sergey Senozhatsky…
ac_timeis now in seconds, do not usektime_to_timespec64()
Please help me out here - which patch introduced the issue which Chris found?
Quoted 1 line
Reported-by Chris Mason <[email protected]>
The Closes: link would be helpful.
Quoted 10 lines
Signed-off-by Sergey Senozhatsky <[email protected]>--- drivers/block/zram/zram_drv.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)drivers/block/zram/zram_drv.c +0
-0
drivers/block/zram/zram_drv.c static ssize_t read_block_state(struct file *file, char __user *buf, · line 1584
Quoted 10 lines
drivers/block/zram/zram_drv.c +2
-4@@ -1579,11 +1579,9 @@ static ssize_t read_block_state(struct file *file, char __user *buf,if (!slot_allocated (zram, index)) goto next; - ts =ktime_to_timespec64 (zram->table[index].attr.ac_time); copied = snprintf(kbuf + written, count, - "%12zd %12lld.%06lu %c%c%c%c%c%c\n", - index, (s64)ts.tv_sec, - ts.tv_nsec / NSEC_PER_USEC, + "%12zd %12u.%06lu %c%c%c%c%c%c\n", + index, zram->table[index].attr.ac_time, 0,
local `ts' is now unused?
Quoted 3 lines
drivers/block/zram/zram_drv.c +0
-0test_slot_flag (zram, index,ZRAM_SAME ) ?'s' :'.' ,test_slot_flag (zram, index,ZRAM_WB ) ?'w' :'.' , test_slot_flag(zram, index, ZRAM_HUGE) ? 'h' : '.',
Sergey Senozhatsky
maintainerRe: [PATCH 2/2] zram: fixup read_block_state()
Quoted 6 lines · Andrew Morton
Quoted 1 line · On Thu, 15 Jan 2026 12:30:06 +0900 Sergey Senozhatsky…
ac_timeis now in seconds, do not usektime_to_timespec64()Please help me out here - which patch introduced the issue which Chris found?
Quoted 3 lines
Quoted 1 line
Reported-by Chris Mason <[email protected]>The Closes: link would be helpful.
I thought that for fixup patches that are still in your tree we don't need Closes: tags. If you prefer to have them, it should be this email:
http://lore.kernel.org/linux-kernel/[email protected]
[..]
Quoted 9 lines
drivers/block/zram/zram_drv.c static ssize_t read_block_state(struct file *file, char __user *buf, · line 1584
Quoted 7 lines
drivers/block/zram/zram_drv.c +2
-4- ts =ktime_to_timespec64 (zram->table[index].attr.ac_time); copied = snprintf(kbuf + written, count, - "%12zd %12lld.%06lu %c%c%c%c%c%c\n", - index, (s64)ts.tv_sec, - ts.tv_nsec / NSEC_PER_USEC, + "%12zd %12u.%06lu %c%c%c%c%c%c\n", + index, zram->table[index].attr.ac_time, 0,local `ts' is now unused?
Oh, yes. Somehow my compiler didn't notice that.
Andrew Morton
maintainerRe: [PATCH 2/2] zram: fixup read_block_state()
Quoted 10 lines · On Fri, 16 Jan 2026 07:54:25 +0900 Sergey Senozhatsky…
Quoted 6 lines · Andrew Morton
Quoted 1 line · On Thu, 15 Jan 2026 12:30:06 +0900 Sergey Senozhatsky…
ac_timeis now in seconds, do not usektime_to_timespec64()Please help me out here - which patch introduced the issue which Chris found?
I figured that out when I fouf Chris's email ;)
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Reported-by Chris Mason <[email protected]>The Closes: link would be helpful.
I thought that for fixup patches that are still in your tree we don't need Closes: tags. If you prefer to have them, it should be this email:
http://lore.kernel.org/linux-kernel/[email protected]
Yep, got it thanks.
Closes: tags are helpful when reviewing, to see all the info. Fixes:
tags aren't useful because the hashes are unstable and because the fix is destined to become part of the thing which it fixes anyway.