[PATCH v2 17/20] mm/zsmalloc: convert get/set_first_obj_offset() to take zpdesc

alexs
2024-07-03T04:02:14Z

From: Hyeonggon Yoo <42.hyeyoo@gmail.com>

Now that all users of get/set_first_obj_offset() are converted
to use zpdesc, convert them to take zpdesc.

Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Signed-off-by: Alex Shi <alexs@kernel.org>
---
mm/zpdesc.h | 6 +++++-
mm/zsmalloc.c | 32 ++++++++++++++++----------------
2 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/mm/zpdesc.h b/mm/zpdesc.h
index 6de3c5d095bd..296cb1ff944b 100644
--- a/mm/zpdesc.h
+++ b/mm/zpdesc.h
@@ -15,6 +15,8 @@
* @next: Next zpdesc in a zspage in zsmalloc zpool
* @handle: For huge zspage in zsmalloc zpool
* @zspage: Pointer to zspage in zsmalloc
+ * @first_obj_offset: First object offset in zsmalloc zpool
+ * @_refcount: Indirectly use by page migration
* @memcg_data: Memory Control Group data.
*
* This struct overlays struct page for now. Do not modify without a good
@@ -31,7 +33,8 @@ struct zpdesc {
unsigned long handle;
};
struct zspage *zspage;
- unsigned long _zp_pad_1;
+ unsigned int first_obj_offset;
+ atomic_t _refcount;
#ifdef CONFIG_SLAB_OBJ_EXT
unsigned long memcg_data;
#endif
@@ -45,6 +48,7 @@ ZPDESC_MATCH(mapping, mops);
ZPDESC_MATCH(index, next);
ZPDESC_MATCH(index, handle);
ZPDESC_MATCH(private, zspage);
+ZPDESC_MATCH(page_type, first_obj_offset);
ZPDESC_MATCH(memcg_data, memcg_data);
#undef ZPDESC_MATCH
static_assert(sizeof(struct zpdesc) <= sizeof(struct page));
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 8b713ac03902..0493f953fcb5 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -494,26 +494,26 @@ static struct zpdesc *get_first_zpdesc(struct zspage *zspage)

#define FIRST_OBJ_PAGE_TYPE_MASK 0xffff

-static inline void reset_first_obj_offset(struct page *page)
+static inline void reset_first_obj_offset(struct zpdesc *zpdesc)
{
- VM_WARN_ON_ONCE(!PageZsmalloc(page));
- page->page_type |= FIRST_OBJ_PAGE_TYPE_MASK;
+ VM_WARN_ON_ONCE(!PageZsmalloc(zpdesc_page(zpdesc)));
+ zpdesc->first_obj_offset |= FIRST_OBJ_PAGE_TYPE_MASK;
}

-static inline unsigned int get_first_obj_offset(struct page *page)
+static inline unsigned int get_first_obj_offset(struct zpdesc *zpdesc)
{
- VM_WARN_ON_ONCE(!PageZsmalloc(page));
- return page->page_type & FIRST_OBJ_PAGE_TYPE_MASK;
+ VM_WARN_ON_ONCE(!PageZsmalloc(zpdesc_page(zpdesc)));
+ return zpdesc->first_obj_offset & FIRST_OBJ_PAGE_TYPE_MASK;
}

-static inline void set_first_obj_offset(struct page *page, unsigned int offset)
+static inline void set_first_obj_offset(struct zpdesc *zpdesc, unsigned int offset)
{
/* With 16 bit available, we can support offsets into 64 KiB pages. */
BUILD_BUG_ON(PAGE_SIZE > SZ_64K);
- VM_WARN_ON_ONCE(!PageZsmalloc(page));
+ VM_WARN_ON_ONCE(!PageZsmalloc(zpdesc_page(zpdesc)));
VM_WARN_ON_ONCE(offset & ~FIRST_OBJ_PAGE_TYPE_MASK);
- page->page_type &= ~FIRST_OBJ_PAGE_TYPE_MASK;
- page->page_type |= offset & FIRST_OBJ_PAGE_TYPE_MASK;
+ zpdesc->first_obj_offset &= ~FIRST_OBJ_PAGE_TYPE_MASK;
+ zpdesc->first_obj_offset |= offset & FIRST_OBJ_PAGE_TYPE_MASK;
}

static inline unsigned int get_freeobj(struct zspage *zspage)
@@ -850,7 +850,7 @@ static void reset_zpdesc(struct zpdesc *zpdesc)
ClearPagePrivate(page);
zpdesc->zspage = NULL;
zpdesc->next = NULL;
- reset_first_obj_offset(page);
+ reset_first_obj_offset(zpdesc);
__ClearPageZsmalloc(page);
}

@@ -934,7 +934,7 @@ static void init_zspage(struct size_class *class, struct zspage *zspage)
struct link_free *link;
void *vaddr;

- set_first_obj_offset(zpdesc_page(zpdesc), off);
+ set_first_obj_offset(zpdesc, off);

vaddr = zpdesc_kmap_atomic(zpdesc);
link = (struct link_free *)vaddr + off / sizeof(*link);
@@ -1589,7 +1589,7 @@ static unsigned long find_alloced_obj(struct size_class *class,
unsigned long handle = 0;
void *addr = zpdesc_kmap_atomic(zpdesc);

- offset = get_first_obj_offset(zpdesc_page(zpdesc));
+ offset = get_first_obj_offset(zpdesc);
offset += class->size * index;

while (offset < PAGE_SIZE) {
@@ -1784,8 +1784,8 @@ static void replace_sub_page(struct size_class *class, struct zspage *zspage,
} while ((zpdesc = get_next_zpdesc(zpdesc)) != NULL);

create_page_chain(class, zspage, zpdescs);
- first_obj_offset = get_first_obj_offset(zpdesc_page(oldzpdesc));
- set_first_obj_offset(zpdesc_page(newzpdesc), first_obj_offset);
+ first_obj_offset = get_first_obj_offset(oldzpdesc);
+ set_first_obj_offset(newzpdesc, first_obj_offset);
if (unlikely(ZsHugePage(zspage)))
newzpdesc->handle = oldzpdesc->handle;
__zpdesc_set_movable(newzpdesc, &zsmalloc_mops);
@@ -1840,7 +1840,7 @@ static int zs_page_migrate(struct page *newpage, struct page *page,
/* the migrate_write_lock protects zpage access via zs_map_object */
migrate_write_lock(zspage);

- offset = get_first_obj_offset(zpdesc_page(zpdesc));
+ offset = get_first_obj_offset(zpdesc);
s_addr = zpdesc_kmap_atomic(zpdesc);

/*
--
2.43.0