Re: [PATCH v5 2/4] mm/zsmalloc: drop pool->lock from zs_free on 64-bit systems

From: Barry Song

Date: Mon Jun 22 2026 - 19:15:55 EST


On Tue, Jun 16, 2026 at 11:13 AM Wenchao Hao <haowenchao22@xxxxxxxxx> wrote:
>
> From: Wenchao Hao <haowenchao@xxxxxxxxxx>
>
> With class_idx encoded in obj, zs_free() can locate the size_class
> without holding pool->lock on 64-bit systems. Page migration also
> takes class->lock and only rewrites the PFN field of obj, so:
>
> 1. read obj locklessly,
> 2. lock the size_class derived from obj's class_idx,
> 3. re-read obj under class->lock to get a stable PFN.
>
> This eliminates the rwlock read-side cacheline bouncing between
> zs_free() and migration/compaction on multi-core systems.
>
> Annotate handle_to_obj()/record_obj() with READ_ONCE()/WRITE_ONCE() to
> prevent load/store tearing on the lockless read path and silence KCSAN
> data race reports.
>
> When ZS_OBJ_CLASS_BITS == 0 (32-bit, or 64-bit with obj too narrow to
> hold class_idx), zs_free() keeps pool->lock.
>
> Reviewed-by: Nhat Pham <nphamcs@xxxxxxxxx>
> Signed-off-by: Wenchao Hao <haowenchao@xxxxxxxxxx>

Reviewed-: Barry Song <baohua@xxxxxxxxxx>

[...]
> +static inline void obj_handle_class_lock(struct zs_pool *pool, unsigned long handle,
> + unsigned long *objp, struct zspage **zspagep,
> + struct size_class **classp)
> + __acquires(&(*classp)->lock)
> +{


Somehow, I feel that obj_handle_class_lock() is a misleading name.
The function clearly does more than just handle class locking—it also
retrieves the object and the zspage.

Best Regards
Barry