[PW_SID:1091436] mm/zsmalloc: reduce lock contention in zs_free()#1881
[PW_SID:1091436] mm/zsmalloc: reduce lock contention in zs_free()#1881linux-riscv-bot wants to merge 4 commits into
Conversation
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>
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 1: "[RFC,1/3] mm/zsmalloc: encode class index in obj value for lockless class lookup" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 2: "[RFC,2/3] mm/zsmalloc: remove pool->lock from zs_free on 64-bit systems" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
|
Patch 3: "[RFC,3/3] mm/zsmalloc: drop class lock before freeing zspage" |
2d4fcdd to
cd9d421
Compare
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