Skip to content

[PW_SID:1091436] mm/zsmalloc: reduce lock contention in zs_free()#1881

Closed
linux-riscv-bot wants to merge 4 commits into
workflow__riscv__fixesfrom
pw1091436
Closed

[PW_SID:1091436] mm/zsmalloc: reduce lock contention in zs_free()#1881
linux-riscv-bot wants to merge 4 commits into
workflow__riscv__fixesfrom
pw1091436

Conversation

@linux-riscv-bot
Copy link
Copy Markdown

PR for series 1091436 applied to workflow__riscv__fixes

Name: mm/zsmalloc: reduce lock contention in zs_free()
URL: https://patchwork.kernel.org/project/linux-riscv/list/?series=1091436
Version: 1

Linux RISC-V bot and others added 4 commits May 2, 2026 08:13
Encode the size class index (class_idx) into the obj value so that
zs_free() can determine the correct size_class without dereferencing
the handle->obj->PFN->zpdesc->zspage->class chain under pool->lock.

OBJ_INDEX_BITS is over-provisioned on 64-bit systems.  For example on
arm64 with default chain_size=8: OBJ_INDEX_BITS=24 but only 10 bits
are actually needed for obj_idx.  We dynamically compute OBJ_CLASS_BITS
as ilog2(ZS_SIZE_CLASSES - 1) + 1 (8 bits for 4K pages, 9 for 64K)
and verify at compile time via static_assert that the three fields
(PFN + class_idx + obj_idx) fit within BITS_PER_LONG.

This encoding is gated by ZS_OBJ_CLASS_IDX, defined only when
BITS_PER_LONG >= 64.  On 32-bit systems the bits do not fit, so
the feature is disabled and the original OBJ_INDEX layout is preserved.

Split OBJ_INDEX into class_idx and obj_idx:

  obj: [PFN | class_idx | obj_idx]
       [_PFN_BITS | OBJ_CLASS_BITS | OBJ_IDX_BITS]

class_idx is invariant across page migration (only PFN changes), so a
lockless read always yields a valid class_idx.

Update obj_to_location(), location_to_obj() and callers accordingly.
Add obj_to_class_idx() helper.  Adjust ZS_MIN_ALLOC_SIZE to use
OBJ_IDX_BITS.

Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
With class_idx now encoded in the obj value (ZS_OBJ_CLASS_IDX),
zs_free() no longer needs pool->lock to locate the size class on
64-bit systems.

The class_idx is invariant across page migration (only PFN changes),
and 64-bit aligned reads are atomic, so a lockless read of the handle
always yields a valid class_idx.  After acquiring class->lock (which
blocks concurrent migration), the handle is re-read to obtain a stable
PFN for the actual free operation.

This eliminates rwlock read-side contention between zs_free() and page
migration/compaction, improving zs_free() scalability on multi-core
systems.

On 32-bit systems (ZS_OBJ_CLASS_IDX not defined), the original
pool->lock path is preserved.

Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
Currently in zs_free(), the class->lock is held until the zspage is
completely freed and the counters are updated. However, freeing pages back
to the buddy allocator requires acquiring the zone lock.

Under heavy memory pressure, zone lock contention can be severe. When this
happens, the CPU holding the class->lock will stall waiting for the zone
lock, thereby blocking all other CPUs attempting to acquire the same
class->lock.

This patch shrinks the critical section of the class->lock to reduce lock
contention. By moving the actual page freeing process outside the
class->lock, we can improve the concurrency performance of zs_free().

Testing on the RADXA O6 platform shows that with 12 CPUs concurrently
performing zs_free() operations, the execution time is reduced by 20%.

Signed-off-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com>
Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
build-rv32-defconfig
Desc: Builds riscv32 defconfig
Duration: 112.97 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
build-rv64-clang-allmodconfig
Desc: Builds riscv64 allmodconfig with Clang, and checks for errors and added warnings
Duration: 1109.42 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
build-rv64-gcc-allmodconfig
Desc: Builds riscv64 allmodconfig with GCC, and checks for errors and added warnings
Duration: 1624.84 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
build-rv64-nommu-k210-defconfig
Desc: Builds riscv64 defconfig with NOMMU for K210
Duration: 19.31 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
build-rv64-nommu-k210-virt
Desc: Builds riscv64 defconfig with NOMMU for the virt platform
Duration: 20.63 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
checkpatch
Desc: Runs checkpatch.pl on the patch
Duration: 1.78 seconds
Result: WARNING
Output:

WARNING: From:/Signed-off-by: email address mismatch: 'From: Wenchao Hao <haowenchao22@gmail.com>' != 'Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com>'

total: 0 errors, 1 warnings, 0 checks, 137 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

Commit 6439b7918b63 ("mm/zsmalloc: encode class index in obj value for lockless class lookup") has style problems, please review.

NOTE: Ignored message types: ALLOC_SIZEOF_STRUCT CAMELCASE COMMIT_LOG_LONG_LINE GIT_COMMIT_ID MACRO_ARG_REUSE NO_AUTHOR_SIGN_OFF

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.
total: 0 errors, 1 warnings, 0 checks, 137 lines checked
WARNING: From:/Signed-off-by: email address mismatch: 'From: Wenchao Hao <haowenchao22@gmail.com>' != 'Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com>'


@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
dtb-warn-rv64
Desc: Checks for Device Tree warnings/errors
Duration: 75.81 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
header-inline
Desc: Detects static functions without inline keyword in header files
Duration: 0.24 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
kdoc
Desc: Detects for kdoc errors
Duration: 0.72 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
module-param
Desc: Detect module_param changes
Duration: 0.24 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
verify-fixes
Desc: Verifies that the Fixes: tags exist
Duration: 0.23 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup"
verify-signedoff
Desc: Verifies that Signed-off-by: tags are correct
Duration: 0.27 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
build-rv32-defconfig
Desc: Builds riscv32 defconfig
Duration: 113.51 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
build-rv64-clang-allmodconfig
Desc: Builds riscv64 allmodconfig with Clang, and checks for errors and added warnings
Duration: 1109.84 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
build-rv64-gcc-allmodconfig
Desc: Builds riscv64 allmodconfig with GCC, and checks for errors and added warnings
Duration: 1628.76 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
build-rv64-nommu-k210-defconfig
Desc: Builds riscv64 defconfig with NOMMU for K210
Duration: 19.39 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
build-rv64-nommu-k210-virt
Desc: Builds riscv64 defconfig with NOMMU for the virt platform
Duration: 20.67 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
checkpatch
Desc: Runs checkpatch.pl on the patch
Duration: 2.61 seconds
Result: WARNING
Output:

WARNING: From:/Signed-off-by: email address mismatch: 'From: Wenchao Hao <haowenchao22@gmail.com>' != 'Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com>'

total: 0 errors, 1 warnings, 0 checks, 43 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

Commit 54ca094ba5dd ("mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems") has style problems, please review.

NOTE: Ignored message types: ALLOC_SIZEOF_STRUCT CAMELCASE COMMIT_LOG_LONG_LINE GIT_COMMIT_ID MACRO_ARG_REUSE NO_AUTHOR_SIGN_OFF

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.
total: 0 errors, 1 warnings, 0 checks, 43 lines checked
WARNING: From:/Signed-off-by: email address mismatch: 'From: Wenchao Hao <haowenchao22@gmail.com>' != 'Signed-off-by: Wenchao Hao <haowenchao@xiaomi.com>'


@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
dtb-warn-rv64
Desc: Checks for Device Tree warnings/errors
Duration: 75.18 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
header-inline
Desc: Detects static functions without inline keyword in header files
Duration: 0.23 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
kdoc
Desc: Detects for kdoc errors
Duration: 0.72 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
module-param
Desc: Detect module_param changes
Duration: 0.24 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
verify-fixes
Desc: Verifies that the Fixes: tags exist
Duration: 0.23 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems"
verify-signedoff
Desc: Verifies that Signed-off-by: tags are correct
Duration: 0.26 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
build-rv32-defconfig
Desc: Builds riscv32 defconfig
Duration: 114.54 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
build-rv64-clang-allmodconfig
Desc: Builds riscv64 allmodconfig with Clang, and checks for errors and added warnings
Duration: 1113.31 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
build-rv64-gcc-allmodconfig
Desc: Builds riscv64 allmodconfig with GCC, and checks for errors and added warnings
Duration: 1619.49 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
build-rv64-nommu-k210-defconfig
Desc: Builds riscv64 defconfig with NOMMU for K210
Duration: 19.28 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
build-rv64-nommu-k210-virt
Desc: Builds riscv64 defconfig with NOMMU for the virt platform
Duration: 20.64 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
checkpatch
Desc: Runs checkpatch.pl on the patch
Duration: 1.52 seconds
Result: WARNING
Output:

CHECK: Alignment should match open parenthesis
#55: FILE: mm/zsmalloc.c:905:
+static void __free_zspage(struct zs_pool *pool, struct size_class *class,
+				struct zspage *zspage)

CHECK: braces {} should be used on all arms of this statement
#77: FILE: mm/zsmalloc.c:1510:
+		if (trylock_zspage(zspage)) {
[...]
+		} else
[...]

CHECK: Alignment should match open parenthesis
#80: FILE: mm/zsmalloc.c:1513:
+			class_stat_sub(class, ZS_OBJS_ALLOCATED,
+				class->objs_per_zspage);

CHECK: Unbalanced braces around else statement
#82: FILE: mm/zsmalloc.c:1515:
+		} else

total: 0 errors, 0 warnings, 4 checks, 58 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

Commit e6cb08ccdf0b ("mm/zsmalloc: drop class lock before freeing zspage") has style problems, please review.

NOTE: Ignored message types: ALLOC_SIZEOF_STRUCT CAMELCASE COMMIT_LOG_LONG_LINE GIT_COMMIT_ID MACRO_ARG_REUSE NO_AUTHOR_SIGN_OFF

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.
total: 0 errors, 0 warnings, 4 checks, 58 lines checked
CHECK: Alignment should match open parenthesis
CHECK: Unbalanced braces around else statement
CHECK: braces {} should be used on all arms of this statement


@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
dtb-warn-rv64
Desc: Checks for Device Tree warnings/errors
Duration: 74.78 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
header-inline
Desc: Detects static functions without inline keyword in header files
Duration: 0.23 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
kdoc
Desc: Detects for kdoc errors
Duration: 0.71 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
module-param
Desc: Detect module_param changes
Duration: 0.24 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
verify-fixes
Desc: Verifies that the Fixes: tags exist
Duration: 0.22 seconds
Result: PASS

@linux-riscv-bot
Copy link
Copy Markdown
Author

Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage"
verify-signedoff
Desc: Verifies that Signed-off-by: tags are correct
Duration: 0.26 seconds
Result: PASS

@linux-riscv-bot linux-riscv-bot force-pushed the workflow__riscv__fixes branch 2 times, most recently from 2d4fcdd to cd9d421 Compare May 14, 2026 08:49
@linux-riscv-bot linux-riscv-bot deleted the pw1091436 branch May 16, 2026 02:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants