FAILED: patch "[PATCH] zram: fix slot lock bit position on big-endian 64-bit" failed to apply to 7.2-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 7.2-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.2.y
git checkout FETCH_HEAD
git cherry-pick -x a8b5875741d416703e19ad8eeac6fce8a12bd6e4
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090337-onshore-thermos-9127@gregkh' --subject-prefix 'PATCH 7.2.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From a8b5875741d416703e19ad8eeac6fce8a12bd6e4 Mon Sep 17 00:00:00 2001
From: David Carlier <[email protected]>
Date: Mon, 10 Aug 2026 21:22:37 +0100
Subject: [PATCH] zram: fix slot lock bit position on big-endian 64-bit
The slot lock is a bit operation on the whole __lock word, which flags and ac_time alias as two u32s. On little-endian the lock bit lands in the position ZRAM_ENTRY_LOCK reserves in flags, so the aliasing works out. On 64-bit big-endian it lands in ac_time instead: with ZRAM_TRACK_ENTRY_ACTIME enabled, storing the access time from mark_slot_accessed() or slot_free() wipes out the held lock bit, letting another CPU take the same slot lock; an access time value with that bit set makes the slot look locked forever.
Shift the lock bit into the flags half of the word on big-endian 64-bit.
drivers/block/zram/zram_drv.c +3 -3
@@ -74,7 +74,7 @@ static __must_check bool slot_trylock(struct zram *zram, unsigned long index) {unsigned long *lock = &zram->table[index].__lock; -if (!test_and_set_bit_lock (ZRAM_ENTRY_LOCK , lock)) { +if (!test_and_set_bit_lock (ZRAM_ENTRY_LOCK_BIT , lock)) {mutex_acquire (&zram->table_lock_map,0 ,1 , _RET_IP_);lock_acquired (&zram->table_lock_map, _RET_IP_);return true;
@@ -88,7 +88,7 @@ static void slot_lock(struct zram *zram, unsigned long index)unsigned long *lock = &zram->table[index].__lock;mutex_acquire (&zram->table_lock_map,0 ,0 , _RET_IP_); -wait_on_bit_lock (lock,ZRAM_ENTRY_LOCK ,TASK_UNINTERRUPTIBLE ); +wait_on_bit_lock (lock,ZRAM_ENTRY_LOCK_BIT ,TASK_UNINTERRUPTIBLE );lock_acquired (&zram->table_lock_map, _RET_IP_); }
@@ -97,7 +97,7 @@ static void slot_unlock(struct zram *zram, unsigned long index)unsigned long *lock = &zram->table[index].__lock;mutex_release (&zram->table_lock_map, _RET_IP_); -clear_and_wake_up_bit (ZRAM_ENTRY_LOCK , lock); +clear_and_wake_up_bit (ZRAM_ENTRY_LOCK_BIT , lock); }static inline bool init_done (struct zram *zram)
drivers/block/zram/zram_drv.h +14 -0
@@ -15,6 +15,7 @@#ifndef _ZRAM_DRV_H_#define _ZRAM_DRV_H_ +#include <asm/byteorder.h> #include <linux/rwsem.h> #include <linux/zsmalloc.h>
@@ -57,6 +58,19 @@ enum zram_pageflags { __NR_ZRAM_PAGEFLAGS, }; +/* +* The slot lock is a bit-wait lock on the whole __lock word, while +* flags and ac_time alias that word as two u32s. The lock bit must +* land in the slot that ZRAM_ENTRY_LOCK reserves in attr.flags; on +* 64-bit big-endian the flags word maps to the upper half of __lock, +* so the bit position has to be shifted up. +*/ +#if defined(CONFIG_64BIT ) && defined(__BIG_ENDIAN) +#define ZRAM_ENTRY_LOCK_BIT (ZRAM_ENTRY_LOCK + 32) +#else +#define ZRAM_ENTRY_LOCK_BIT ZRAM_ENTRY_LOCK +#endif +/* * Allocated for each disk page. We use bit-lock (ZRAM_ENTRY_LOCK bit * of flags) to save memory. There can be plenty of entries and standard
Sasha Levin
maintainerPATCH 1/2 zram: move lockmap to be per-zram instead per table
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit dbb7ba9c7fa81a48ed2a108ad684cf3655f3ae4b ]
Patch series "zram: lockmap tweaks".
This patch (of 2):
The zram object contains an array zram_table_entry. Each one has a `lock' variable and each has a matching struct lockdep_map. This mimics a struct mutex.
It uses always the same key for all lockdep_map instances. This makes it look like the same lock to lockdep. Therefore it could be reduced to have one lockdep_map per struct zram.
Use only one struct lockdep_map per struct zram.
Stable-dep-of: a8b5875741d4 ("zram: fix slot lock bit position on big-endian 64-bit")
--- drivers/block/zram/zram_drv.c | 21 +++++++++------------ drivers/block/zram/zram_drv.h | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-)
drivers/block/zram/zram_drv.c +9 -12
@@ -57,14 +57,12 @@ static size_t huge_class_size;static const struct block_device_operations zram_devops;static void slot_free (struct zram *zram,u32 index); -#define slot_dep_map (zram, index) (&(zram)->table[(index)].dep_map) -static void slot_lock_init (struct zram *zram,u32 index) +static void slot_lock_init (struct zram *zram) {static struct lock_class_key __key; -lockdep_init_map (slot_dep_map (zram, index),"zram->table[index].lock" , - &__key,0 ); +lockdep_init_map (&zram->table_lock_map,"zram->table[index].lock" , &__key,0 ); }/*
@@ -84,8 +82,8 @@ static __must_check bool slot_trylock(struct zram *zram, u32 index)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_); -lock_acquired (slot_dep_map (zram, index), _RET_IP_); +mutex_acquire (&zram->table_lock_map,0 ,1 , _RET_IP_); +lock_acquired (&zram->table_lock_map, _RET_IP_);return true; }
@@ -96,16 +94,16 @@ static void slot_lock(struct zram *zram, u32 index) {unsigned long *lock = &zram->table[index].__lock; -mutex_acquire (slot_dep_map (zram, index),0 ,0 , _RET_IP_); +mutex_acquire (&zram->table_lock_map,0 ,0 , _RET_IP_);wait_on_bit_lock (lock,ZRAM_ENTRY_LOCK ,TASK_UNINTERRUPTIBLE ); -lock_acquired (slot_dep_map (zram, index), _RET_IP_); +lock_acquired (&zram->table_lock_map, _RET_IP_); }static void slot_unlock (struct zram *zram,u32 index) {unsigned long *lock = &zram->table[index].__lock; -mutex_release (slot_dep_map (zram, index), _RET_IP_); +mutex_release (&zram->table_lock_map, _RET_IP_);clear_and_wake_up_bit (ZRAM_ENTRY_LOCK , lock); }
@@ -1984,7 +1982,7 @@ static void zram_meta_free(struct zram *zram, u64 disksize)static bool zram_meta_alloc (struct zram *zram,u64 disksize) { -size_t num_pages, index; +size_t num_pages; num_pages = disksize >>PAGE_SHIFT ; zram->table =vzalloc (array_size (num_pages,sizeof (*zram->table)));
@@ -2001,8 +1999,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize)if (!huge_class_size) huge_class_size =zs_huge_class_size (zram->mem_pool); -for (index =0 ; index < num_pages; index++) -slot_lock_init (zram, index); +slot_lock_init (zram);return true; }
drivers/block/zram/zram_drv.h +1 -1
@@ -74,7 +74,6 @@ struct zram_table_entry {#endif } attr; }; -struct lockdep_map dep_map; };struct zram_stats {
@@ -107,6 +106,7 @@ struct zram_stats {struct zram {struct zram_table_entry *table; +struct lockdep_map table_lock_map;struct zs_pool *mem_pool;struct zcomp *comps[ZRAM_MAX_COMPS ];struct zcomp_params params[ZRAM_MAX_COMPS ];
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 zram: fix slot lock bit position on big-endian 64-bit
From: David Carlier <[email protected]>
[ Upstream commit a8b5875741d416703e19ad8eeac6fce8a12bd6e4 ]
The slot lock is a bit operation on the whole __lock word, which flags and ac_time alias as two u32s. On little-endian the lock bit lands in the position ZRAM_ENTRY_LOCK reserves in flags, so the aliasing works out. On 64-bit big-endian it lands in ac_time instead: with ZRAM_TRACK_ENTRY_ACTIME enabled, storing the access time from mark_slot_accessed() or slot_free() wipes out the held lock bit, letting another CPU take the same slot lock; an access time value with that bit set makes the slot look locked forever.
Shift the lock bit into the flags half of the word on big-endian 64-bit.
--- drivers/block/zram/zram_drv.c | 6 +++--- drivers/block/zram/zram_drv.h | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-)
drivers/block/zram/zram_drv.c +3 -3
@@ -81,7 +81,7 @@ static __must_check bool slot_trylock(struct zram *zram, u32 index) {unsigned long *lock = &zram->table[index].__lock; -if (!test_and_set_bit_lock (ZRAM_ENTRY_LOCK , lock)) { +if (!test_and_set_bit_lock (ZRAM_ENTRY_LOCK_BIT , lock)) {mutex_acquire (&zram->table_lock_map,0 ,1 , _RET_IP_);lock_acquired (&zram->table_lock_map, _RET_IP_);return true;
@@ -95,7 +95,7 @@ static void slot_lock(struct zram *zram, u32 index)unsigned long *lock = &zram->table[index].__lock;mutex_acquire (&zram->table_lock_map,0 ,0 , _RET_IP_); -wait_on_bit_lock (lock,ZRAM_ENTRY_LOCK ,TASK_UNINTERRUPTIBLE ); +wait_on_bit_lock (lock,ZRAM_ENTRY_LOCK_BIT ,TASK_UNINTERRUPTIBLE );lock_acquired (&zram->table_lock_map, _RET_IP_); }
@@ -104,7 +104,7 @@ static void slot_unlock(struct zram *zram, u32 index)unsigned long *lock = &zram->table[index].__lock;mutex_release (&zram->table_lock_map, _RET_IP_); -clear_and_wake_up_bit (ZRAM_ENTRY_LOCK , lock); +clear_and_wake_up_bit (ZRAM_ENTRY_LOCK_BIT , lock); }static inline bool init_done (struct zram *zram)
drivers/block/zram/zram_drv.h +14 -0
@@ -15,6 +15,7 @@#ifndef _ZRAM_DRV_H_#define _ZRAM_DRV_H_ +#include <asm/byteorder.h> #include <linux/rwsem.h> #include <linux/zsmalloc.h>
@@ -57,6 +58,19 @@ enum zram_pageflags { __NR_ZRAM_PAGEFLAGS, }; +/* +* The slot lock is a bit-wait lock on the whole __lock word, while +* flags and ac_time alias that word as two u32s. The lock bit must +* land in the slot that ZRAM_ENTRY_LOCK reserves in attr.flags; on +* 64-bit big-endian the flags word maps to the upper half of __lock, +* so the bit position has to be shifted up. +*/ +#if defined(CONFIG_64BIT ) && defined(__BIG_ENDIAN) +#define ZRAM_ENTRY_LOCK_BIT (ZRAM_ENTRY_LOCK + 32) +#else +#define ZRAM_ENTRY_LOCK_BIT ZRAM_ENTRY_LOCK +#endif +/* * Allocated for each disk page. We use bit-lock (ZRAM_ENTRY_LOCK bit * of flags) to save memory. There can be plenty of entries and standard
Signature · 1 line
2.53.0