Re: [PATCH 5/7] zsmalloc: embed struct zs_handle into zram and zswap entries

From: Yosry Ahmed

Date: Thu Nov 05 2026 - 12:46:22 EST


> +#ifdef CONFIG_ZSMALLOC_REBIND_HANDLE
> +/**
> + * zs_rebind_handle() - Rebind an allocated object to a new handle.
> + * @pool: pool the object belongs to
> + * @dst: unallocated destination handle (must not be on the stack)
> + * @src: source handle that currently owns the object
> + *
> + * Rebinds the object from @src to @dst, updating the object header so
> + * compaction and page migration update @dst instead of @src, and resets
> + * @src.
> + */
> +void zs_rebind_handle(struct zs_pool *pool, struct zs_handle *dst,
> + struct zs_handle *src)
> +{
> + struct size_class *class;
> + struct zspage *zspage;
> + unsigned long obj;
> +
> + if (WARN_ON_ONCE(object_is_on_stack(dst) ||
> + zs_handle_is_allocated(dst) ||
> + !zs_handle_is_allocated(src)))
> + return;
> +
> + obj_class_get_and_lock(pool, src, &obj, &zspage, &class);
> +
> + if (likely(!ZsHugePage(zspage))) {
> + struct zpdesc *zpdesc;
> + struct link_free *link;
> + unsigned int obj_idx;
> + unsigned long off;
> + void *vaddr;

I think this would be easier to read if you move the declarations to the
top of the function, so that the different logic in the branches is more
obvious.

> +
> + obj_to_location(obj, &zpdesc, &obj_idx);
> + off = offset_in_page(class->size * obj_idx);
> + vaddr = kmap_local_zpdesc(zpdesc);
> + link = (struct link_free *)(vaddr + off);
> + link->handle = (unsigned long)dst | OBJ_ALLOCATED_TAG;
> + kunmap_local(vaddr);
> + } else {
> + zspage->first_zpdesc->handle =
> + (unsigned long)dst | OBJ_ALLOCATED_TAG;
> + }
> +
> + record_obj(dst, obj);
> + record_obj(src, 0);
> + spin_unlock(&class->lock);
> +}
> +EXPORT_SYMBOL_GPL(zs_rebind_handle);
> +#endif