From: alexs@kernel.org
To: Vitaly Wool <vitaly.wool@konsulko.com>,
Miaohe Lin <linmiaohe@huawei.com>,
Andrew Morton <akpm@linux-foundation.org>,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
minchan@kernel.org, willy@infradead.org,
senozhatsky@chromium.org, david@redhat.com, 42.hyeyoo@gmail.com,
Yosry Ahmed <yosryahmed@google.com>,
nphamcs@gmail.com
Cc: Alex Shi <alexs@kernel.org>
Subject: [PATCH v7 02/21] mm/zsmalloc: use zpdesc in trylock_zspage()/lock_zspage()
Date: Mon, 2 Sep 2024 15:21:13 +0800 [thread overview]
Message-ID: <20240902072136.578720-3-alexs@kernel.org> (raw)
In-Reply-To: <20240902072136.578720-1-alexs@kernel.org>
From: Alex Shi <alexs@kernel.org>
To use zpdesc in trylock_zspage()/lock_zspage() funcs, we add couple of helpers:
zpdesc_lock()/zpdesc_unlock()/zpdesc_trylock()/zpdesc_wait_locked() and
zpdesc_get()/zpdesc_put() for this purpose.
Here we use the folio series func in guts for 2 reasons, one zswap.zpool
only get single page, and use folio could save some compound_head checking;
two, folio_put could bypass devmap checking that we don't need.
BTW, thanks Intel LKP found a build warning on the patch.
Originally-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Signed-off-by: Alex Shi <alexs@kernel.org>
---
mm/zpdesc.h | 30 ++++++++++++++++++++++++
mm/zsmalloc.c | 64 ++++++++++++++++++++++++++++++++++-----------------
2 files changed, 73 insertions(+), 21 deletions(-)
diff --git a/mm/zpdesc.h b/mm/zpdesc.h
index 721ef8861131..782b5ad67cda 100644
--- a/mm/zpdesc.h
+++ b/mm/zpdesc.h
@@ -69,4 +69,34 @@ static_assert(sizeof(struct zpdesc) <= sizeof(struct page));
const struct page *: (const struct zpdesc *)(p), \
struct page *: (struct zpdesc *)(p)))
+static inline void zpdesc_lock(struct zpdesc *zpdesc)
+{
+ folio_lock(zpdesc_folio(zpdesc));
+}
+
+static inline bool zpdesc_trylock(struct zpdesc *zpdesc)
+{
+ return folio_trylock(zpdesc_folio(zpdesc));
+}
+
+static inline void zpdesc_unlock(struct zpdesc *zpdesc)
+{
+ folio_unlock(zpdesc_folio(zpdesc));
+}
+
+static inline void zpdesc_wait_locked(struct zpdesc *zpdesc)
+{
+ folio_wait_locked(zpdesc_folio(zpdesc));
+}
+
+static inline void zpdesc_get(struct zpdesc *zpdesc)
+{
+ folio_get(zpdesc_folio(zpdesc));
+}
+
+static inline void zpdesc_put(struct zpdesc *zpdesc)
+{
+ folio_put(zpdesc_folio(zpdesc));
+}
+
#endif
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 5d3e27083c72..9806b1629880 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -433,13 +433,17 @@ static __maybe_unused int is_first_page(struct page *page)
return PagePrivate(page);
}
+static inline bool is_first_zpdesc(struct zpdesc *zpdesc)
+{
+ return PagePrivate(zpdesc_page(zpdesc));
+}
+
/* Protected by class->lock */
static inline int get_zspage_inuse(struct zspage *zspage)
{
return zspage->inuse;
}
-
static inline void mod_zspage_inuse(struct zspage *zspage, int val)
{
zspage->inuse += val;
@@ -453,6 +457,14 @@ static inline struct page *get_first_page(struct zspage *zspage)
return first_page;
}
+static struct zpdesc *get_first_zpdesc(struct zspage *zspage)
+{
+ struct zpdesc *first_zpdesc = zspage->first_zpdesc;
+
+ VM_BUG_ON_PAGE(!is_first_zpdesc(first_zpdesc), zpdesc_page(first_zpdesc));
+ return first_zpdesc;
+}
+
#define FIRST_OBJ_PAGE_TYPE_MASK 0xffffff
static inline unsigned int get_first_obj_offset(struct page *page)
@@ -739,6 +751,16 @@ static struct page *get_next_page(struct page *page)
return (struct page *)page->index;
}
+static struct zpdesc *get_next_zpdesc(struct zpdesc *zpdesc)
+{
+ struct zspage *zspage = get_zspage(zpdesc_page(zpdesc));
+
+ if (unlikely(ZsHugePage(zspage)))
+ return NULL;
+
+ return zpdesc->next;
+}
+
/**
* obj_to_location - get (<page>, <obj_idx>) from encoded object value
* @obj: the encoded object value
@@ -808,11 +830,11 @@ static void reset_page(struct page *page)
static int trylock_zspage(struct zspage *zspage)
{
- struct page *cursor, *fail;
+ struct zpdesc *cursor, *fail;
- for (cursor = get_first_page(zspage); cursor != NULL; cursor =
- get_next_page(cursor)) {
- if (!trylock_page(cursor)) {
+ for (cursor = get_first_zpdesc(zspage); cursor != NULL; cursor =
+ get_next_zpdesc(cursor)) {
+ if (!zpdesc_trylock(cursor)) {
fail = cursor;
goto unlock;
}
@@ -820,9 +842,9 @@ static int trylock_zspage(struct zspage *zspage)
return 1;
unlock:
- for (cursor = get_first_page(zspage); cursor != fail; cursor =
- get_next_page(cursor))
- unlock_page(cursor);
+ for (cursor = get_first_zpdesc(zspage); cursor != fail; cursor =
+ get_next_zpdesc(cursor))
+ zpdesc_unlock(cursor);
return 0;
}
@@ -1651,7 +1673,7 @@ static int putback_zspage(struct size_class *class, struct zspage *zspage)
*/
static void lock_zspage(struct zspage *zspage)
{
- struct page *curr_page, *page;
+ struct zpdesc *curr_zpdesc, *zpdesc;
/*
* Pages we haven't locked yet can be migrated off the list while we're
@@ -1663,24 +1685,24 @@ static void lock_zspage(struct zspage *zspage)
*/
while (1) {
migrate_read_lock(zspage);
- page = get_first_page(zspage);
- if (trylock_page(page))
+ zpdesc = get_first_zpdesc(zspage);
+ if (zpdesc_trylock(zpdesc))
break;
- get_page(page);
+ zpdesc_get(zpdesc);
migrate_read_unlock(zspage);
- wait_on_page_locked(page);
- put_page(page);
+ zpdesc_wait_locked(zpdesc);
+ zpdesc_put(zpdesc);
}
- curr_page = page;
- while ((page = get_next_page(curr_page))) {
- if (trylock_page(page)) {
- curr_page = page;
+ curr_zpdesc = zpdesc;
+ while ((zpdesc = get_next_zpdesc(curr_zpdesc))) {
+ if (zpdesc_trylock(zpdesc)) {
+ curr_zpdesc = zpdesc;
} else {
- get_page(page);
+ zpdesc_get(zpdesc);
migrate_read_unlock(zspage);
- wait_on_page_locked(page);
- put_page(page);
+ zpdesc_wait_locked(zpdesc);
+ zpdesc_put(zpdesc);
migrate_read_lock(zspage);
}
}
--
2.46.0
next prev parent reply other threads:[~2024-09-02 7:16 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-02 7:21 [PATCH v7 00/21] mm/zsmalloc: add zpdesc memory descriptor for zswap.zpool alexs
2024-09-02 7:21 ` [PATCH v7 01/21] " alexs
2024-12-03 16:51 ` Matthew Wilcox
2024-09-02 7:21 ` alexs [this message]
2024-09-02 7:21 ` [PATCH v7 03/21] mm/zsmalloc: convert __zs_map_object/__zs_unmap_object to use zpdesc alexs
2024-09-02 7:21 ` [PATCH v7 04/21] mm/zsmalloc: add and use pfn/zpdesc seeking funcs alexs
2024-09-02 7:21 ` [PATCH v7 05/21] mm/zsmalloc: convert obj_malloc() to use zpdesc alexs
2024-09-02 7:21 ` [PATCH v7 06/21] mm/zsmalloc: convert create_page_chain() and its users " alexs
2024-09-02 7:21 ` [PATCH v7 07/21] mm/zsmalloc: convert obj_allocated() and related helpers " alexs
2024-09-02 7:21 ` [PATCH v7 08/21] mm/zsmalloc: convert init_zspage() " alexs
2024-09-02 7:21 ` [PATCH v7 09/21] mm/zsmalloc: convert obj_to_page() and zs_free() " alexs
2024-09-02 7:21 ` [PATCH v7 10/21] mm/zsmalloc: add zpdesc_is_isolated()/zpdesc_zone() helper for zs_page_migrate() alexs
2024-09-02 7:21 ` [PATCH v7 11/21] mm/zsmalloc: rename reset_page to reset_zpdesc and use zpdesc in it alexs
2024-09-02 7:21 ` [PATCH v7 12/21] mm/zsmalloc: convert __free_zspage() to use zdsesc alexs
2024-09-02 7:21 ` [PATCH v7 13/21] mm/zsmalloc: convert location_to_obj() to take zpdesc alexs
2024-09-02 7:21 ` [PATCH v7 14/21] mm/zsmalloc: convert migrate_zspage() to use zpdesc alexs
2024-09-02 7:21 ` [PATCH v7 15/21] mm/zsmalloc: convert get_zspage() to take zpdesc alexs
2024-09-02 7:21 ` [PATCH v7 16/21] mm/zsmalloc: convert SetZsPageMovable and remove unused funcs alexs
2024-09-02 7:21 ` [PATCH v7 17/21] mm/zsmalloc: convert get/set_first_obj_offset() to take zpdesc alexs
2024-09-02 7:21 ` [PATCH v7 18/21] mm/zsmalloc: introduce __zpdesc_clear_movable alexs
2024-09-02 7:21 ` [PATCH v7 19/21] mm/zsmalloc: introduce __zpdesc_clear/set_zsmalloc() alexs
2024-09-02 7:21 ` [PATCH v7 20/21] mm/zsmalloc: introduce zpdesc_clear_first() helper alexs
2024-09-02 7:21 ` [PATCH v7 21/21] mm/zsmalloc: update comments for page->zpdesc changes alexs
2024-09-03 3:35 ` [PATCH v7 00/21] mm/zsmalloc: add zpdesc memory descriptor for zswap.zpool Sergey Senozhatsky
2024-09-03 3:45 ` Sergey Senozhatsky
2024-09-03 8:01 ` Alex Shi
2024-09-04 6:54 ` Alex Shi
2024-09-04 20:04 ` Vishal Moola
2024-09-12 2:28 ` Alex Shi
2024-12-02 20:05 ` Vishal Moola
2024-12-03 13:58 ` Alex Shi
2024-12-04 14:01 ` Hyeonggon Yoo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240902072136.578720-3-alexs@kernel.org \
--to=alexs@kernel.org \
--cc=42.hyeyoo@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=david@redhat.com \
--cc=linmiaohe@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=minchan@kernel.org \
--cc=nphamcs@gmail.com \
--cc=senozhatsky@chromium.org \
--cc=vitaly.wool@konsulko.com \
--cc=willy@infradead.org \
--cc=yosryahmed@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.