Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

zram: use u32 for entry ac_time tracking

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.

Link: https://lkml.kernel.org/r/d7c0b48450c70eeb5fd8acd6ecd23593f30dbf1f.1765775954.git.senozhatsky@chromium.org
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Suggested-by: David Stevens <stevensd@google.com>
Cc: Brian Geffon <bgeffon@google.com>
Cc: Minchan Kim <minchan@google.com>
Cc: Richard Chang <richardycc@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Sergey Senozhatsky and committed by
Andrew Morton
2e8ff2f5 0327a862

+37 -32
+30 -30
drivers/block/zram/zram_drv.c
··· 81 81 */ 82 82 static __must_check bool zram_slot_trylock(struct zram *zram, u32 index) 83 83 { 84 - unsigned long *lock = &zram->table[index].flags; 84 + unsigned long *lock = &zram->table[index].__lock; 85 85 86 86 if (!test_and_set_bit_lock(ZRAM_ENTRY_LOCK, lock)) { 87 87 mutex_acquire(slot_dep_map(zram, index), 0, 1, _RET_IP_); ··· 94 94 95 95 static void zram_slot_lock(struct zram *zram, u32 index) 96 96 { 97 - unsigned long *lock = &zram->table[index].flags; 97 + unsigned long *lock = &zram->table[index].__lock; 98 98 99 99 mutex_acquire(slot_dep_map(zram, index), 0, 0, _RET_IP_); 100 100 wait_on_bit_lock(lock, ZRAM_ENTRY_LOCK, TASK_UNINTERRUPTIBLE); ··· 103 103 104 104 static void zram_slot_unlock(struct zram *zram, u32 index) 105 105 { 106 - unsigned long *lock = &zram->table[index].flags; 106 + unsigned long *lock = &zram->table[index].__lock; 107 107 108 108 mutex_release(slot_dep_map(zram, index), _RET_IP_); 109 109 clear_and_wake_up_bit(ZRAM_ENTRY_LOCK, lock); ··· 130 130 } 131 131 132 132 static bool zram_test_flag(struct zram *zram, u32 index, 133 - enum zram_pageflags flag) 133 + enum zram_pageflags flag) 134 134 { 135 - return zram->table[index].flags & BIT(flag); 135 + return zram->table[index].attr.flags & BIT(flag); 136 136 } 137 137 138 138 static void zram_set_flag(struct zram *zram, u32 index, 139 - enum zram_pageflags flag) 139 + enum zram_pageflags flag) 140 140 { 141 - zram->table[index].flags |= BIT(flag); 141 + zram->table[index].attr.flags |= BIT(flag); 142 142 } 143 143 144 144 static void zram_clear_flag(struct zram *zram, u32 index, 145 - enum zram_pageflags flag) 145 + enum zram_pageflags flag) 146 146 { 147 - zram->table[index].flags &= ~BIT(flag); 147 + zram->table[index].attr.flags &= ~BIT(flag); 148 148 } 149 149 150 150 static size_t zram_get_obj_size(struct zram *zram, u32 index) 151 151 { 152 - return zram->table[index].flags & (BIT(ZRAM_FLAG_SHIFT) - 1); 152 + return zram->table[index].attr.flags & (BIT(ZRAM_FLAG_SHIFT) - 1); 153 153 } 154 154 155 - static void zram_set_obj_size(struct zram *zram, 156 - u32 index, size_t size) 155 + static void zram_set_obj_size(struct zram *zram, u32 index, size_t size) 157 156 { 158 - unsigned long flags = zram->table[index].flags >> ZRAM_FLAG_SHIFT; 157 + unsigned long flags = zram->table[index].attr.flags >> ZRAM_FLAG_SHIFT; 159 158 160 - zram->table[index].flags = (flags << ZRAM_FLAG_SHIFT) | size; 159 + zram->table[index].attr.flags = (flags << ZRAM_FLAG_SHIFT) | size; 161 160 } 162 161 163 162 static inline bool zram_allocated(struct zram *zram, u32 index) ··· 207 208 * Clear previous priority value first, in case if we recompress 208 209 * further an already recompressed page 209 210 */ 210 - zram->table[index].flags &= ~(ZRAM_COMP_PRIORITY_MASK << 211 - ZRAM_COMP_PRIORITY_BIT1); 212 - zram->table[index].flags |= (prio << ZRAM_COMP_PRIORITY_BIT1); 211 + zram->table[index].attr.flags &= ~(ZRAM_COMP_PRIORITY_MASK << 212 + ZRAM_COMP_PRIORITY_BIT1); 213 + zram->table[index].attr.flags |= (prio << ZRAM_COMP_PRIORITY_BIT1); 213 214 } 214 215 215 216 static inline u32 zram_get_priority(struct zram *zram, u32 index) 216 217 { 217 - u32 prio = zram->table[index].flags >> ZRAM_COMP_PRIORITY_BIT1; 218 + u32 prio = zram->table[index].attr.flags >> ZRAM_COMP_PRIORITY_BIT1; 218 219 219 220 return prio & ZRAM_COMP_PRIORITY_MASK; 220 221 } ··· 224 225 zram_clear_flag(zram, index, ZRAM_IDLE); 225 226 zram_clear_flag(zram, index, ZRAM_PP_SLOT); 226 227 #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME 227 - zram->table[index].ac_time = ktime_get_boottime(); 228 + zram->table[index].attr.ac_time = (u32)ktime_get_boottime_seconds(); 228 229 #endif 229 230 } 230 231 ··· 446 447 447 448 #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME 448 449 is_idle = !cutoff || 449 - ktime_after(cutoff, zram->table[index].ac_time); 450 + ktime_after(cutoff, zram->table[index].attr.ac_time); 450 451 #endif 451 452 if (is_idle) 452 453 zram_set_flag(zram, index, ZRAM_IDLE); ··· 460 461 const char *buf, size_t len) 461 462 { 462 463 struct zram *zram = dev_to_zram(dev); 463 - ktime_t cutoff_time = 0; 464 + ktime_t cutoff = 0; 464 465 465 466 if (!sysfs_streq(buf, "all")) { 466 467 /* 467 468 * If it did not parse as 'all' try to treat it as an integer 468 469 * when we have memory tracking enabled. 469 470 */ 470 - u64 age_sec; 471 + u32 age_sec; 471 472 472 - if (IS_ENABLED(CONFIG_ZRAM_TRACK_ENTRY_ACTIME) && !kstrtoull(buf, 0, &age_sec)) 473 - cutoff_time = ktime_sub(ktime_get_boottime(), 474 - ns_to_ktime(age_sec * NSEC_PER_SEC)); 473 + if (IS_ENABLED(CONFIG_ZRAM_TRACK_ENTRY_ACTIME) && 474 + !kstrtouint(buf, 0, &age_sec)) 475 + cutoff = ktime_sub((u32)ktime_get_boottime_seconds(), 476 + age_sec); 475 477 else 476 478 return -EINVAL; 477 479 } ··· 482 482 return -EINVAL; 483 483 484 484 /* 485 - * A cutoff_time of 0 marks everything as idle, this is the 485 + * A cutoff of 0 marks everything as idle, this is the 486 486 * "all" behavior. 487 487 */ 488 - mark_idle(zram, cutoff_time); 488 + mark_idle(zram, cutoff); 489 489 return len; 490 490 } 491 491 ··· 1588 1588 if (!zram_allocated(zram, index)) 1589 1589 goto next; 1590 1590 1591 - ts = ktime_to_timespec64(zram->table[index].ac_time); 1591 + ts = ktime_to_timespec64(zram->table[index].attr.ac_time); 1592 1592 copied = snprintf(kbuf + written, count, 1593 1593 "%12zd %12lld.%06lu %c%c%c%c%c%c\n", 1594 1594 index, (s64)ts.tv_sec, ··· 2013 2013 unsigned long handle; 2014 2014 2015 2015 #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME 2016 - zram->table[index].ac_time = 0; 2016 + zram->table[index].attr.ac_time = 0; 2017 2017 #endif 2018 2018 2019 2019 zram_clear_flag(zram, index, ZRAM_IDLE); ··· 3286 3286 struct zram_table_entry zram_te; 3287 3287 int ret; 3288 3288 3289 - BUILD_BUG_ON(__NR_ZRAM_PAGEFLAGS > sizeof(zram_te.flags) * 8); 3289 + BUILD_BUG_ON(__NR_ZRAM_PAGEFLAGS > sizeof(zram_te.attr.flags) * 8); 3290 3290 3291 3291 ret = cpuhp_setup_state_multi(CPUHP_ZCOMP_PREPARE, "block/zram:prepare", 3292 3292 zcomp_cpu_up_prepare, zcomp_cpu_dead);
+7 -2
drivers/block/zram/zram_drv.h
··· 65 65 */ 66 66 struct zram_table_entry { 67 67 unsigned long handle; 68 - unsigned long flags; 68 + union { 69 + unsigned long __lock; 70 + struct attr { 71 + u32 flags; 69 72 #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME 70 - ktime_t ac_time; 73 + u32 ac_time; 71 74 #endif 75 + } attr; 76 + }; 72 77 struct lockdep_map dep_map; 73 78 }; 74 79