From: Kanchana P Sridhar <kanchana.p.sridhar@intel.com>
To: linux-kernel@vger.kernel.org, linux-mm@kvack.org,
hannes@cmpxchg.org, yosryahmed@google.com, nphamcs@gmail.com,
chengming.zhou@linux.dev, usamaarif642@gmail.com,
ryan.roberts@arm.com, 21cnbao@gmail.com,
akpm@linux-foundation.org
Cc: wajdi.k.feghali@intel.com, vinodh.gopal@intel.com,
kanchana.p.sridhar@intel.com
Subject: [PATCH v1 2/2] mm: zswap: zswap_store_pages() simplifications for batching.
Date: Wed, 27 Nov 2024 14:53:24 -0800 [thread overview]
Message-ID: <20241127225324.6770-3-kanchana.p.sridhar@intel.com> (raw)
In-Reply-To: <20241127225324.6770-1-kanchana.p.sridhar@intel.com>
In order to set up zswap_store_pages() to enable a clean batching
implementation in [1], this patch implements the following changes:
1) Addition of zswap_alloc_entries() which will allocate zswap entries for
all pages in the specified range for the folio, upfront. If this fails,
we return an error status to zswap_store().
2) Addition of zswap_compress_pages() that calls zswap_compress() for each
page, and returns false if any zswap_compress() fails, so
zswap_store_page() can cleanup resources allocated and return an error
status to zswap_store().
3) A "store_pages_failed" label that is a catch-all for all failure points
in zswap_store_pages(). This facilitates cleaner error handling within
zswap_store_pages(), which will become important for IAA compress
batching in [1].
[1]: https://patchwork.kernel.org/project/linux-mm/list/?series=911935
Signed-off-by: Kanchana P Sridhar <kanchana.p.sridhar@intel.com>
---
mm/zswap.c | 93 +++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 71 insertions(+), 22 deletions(-)
diff --git a/mm/zswap.c b/mm/zswap.c
index b09d1023e775..db80c66e2205 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -1409,9 +1409,56 @@ static void shrink_worker(struct work_struct *w)
* main API
**********************************/
+static bool zswap_compress_pages(struct page *pages[],
+ struct zswap_entry *entries[],
+ u8 nr_pages,
+ struct zswap_pool *pool)
+{
+ u8 i;
+
+ for (i = 0; i < nr_pages; ++i) {
+ if (!zswap_compress(pages[i], entries[i], pool))
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Allocate @nr zswap entries for storing @nr pages in a folio.
+ * If any one of the entry allocation fails, delete all entries allocated
+ * thus far, and return false.
+ * If @nr entries are successfully allocated, set each entry's "handle"
+ * to "ERR_PTR(-EINVAL)" to denote that the handle has not yet been allocated.
+ */
+static bool zswap_alloc_entries(struct zswap_entry *entries[], int node_id, u8 nr)
+{
+ u8 i;
+
+ for (i = 0; i < nr; ++i) {
+ entries[i] = zswap_entry_cache_alloc(GFP_KERNEL, node_id);
+ if (!entries[i]) {
+ u8 j;
+
+ zswap_reject_kmemcache_fail++;
+ for (j = 0; j < i; ++j)
+ zswap_entry_cache_free(entries[j]);
+ return false;
+ }
+
+ entries[i]->handle = (unsigned long)ERR_PTR(-EINVAL);
+ }
+
+ return true;
+}
+
/*
* Store multiple pages in @folio, starting from the page at index @si up to
* and including the page at index @ei.
+ * The error handling from all failure points is handled by the
+ * "store_pages_failed" label, based on the initial ERR_PTR(-EINVAL) value for
+ * the zswap_entry's handle set by zswap_alloc_entries(), and the fact that the
+ * entry's handle is subsequently modified only upon a successful zpool_malloc().
*/
static ssize_t zswap_store_pages(struct folio *folio,
long si,
@@ -1419,26 +1466,25 @@ static ssize_t zswap_store_pages(struct folio *folio,
struct obj_cgroup *objcg,
struct zswap_pool *pool)
{
- struct page *page;
- swp_entry_t page_swpentry;
- struct zswap_entry *entry, *old;
+ struct zswap_entry *entries[SWAP_CRYPTO_BATCH_SIZE], *old;
+ struct page *pages[SWAP_CRYPTO_BATCH_SIZE];
size_t compressed_bytes = 0;
u8 nr_pages = ei - si + 1;
u8 i;
- for (i = 0; i < nr_pages; ++i) {
- page = folio_page(folio, si + i);
- page_swpentry = page_swap_entry(page);
+ /* allocate entries */
+ if (!zswap_alloc_entries(entries, folio_nid(folio), nr_pages))
+ return -EINVAL;
- /* allocate entry */
- entry = zswap_entry_cache_alloc(GFP_KERNEL, page_to_nid(page));
- if (!entry) {
- zswap_reject_kmemcache_fail++;
- return -EINVAL;
- }
+ for (i = 0; i < nr_pages; ++i)
+ pages[i] = folio_page(folio, si + i);
- if (!zswap_compress(page, entry, pool))
- goto compress_failed;
+ if (!zswap_compress_pages(pages, entries, nr_pages, pool))
+ goto store_pages_failed;
+
+ for (i = 0; i < nr_pages; ++i) {
+ swp_entry_t page_swpentry = page_swap_entry(pages[i]);
+ struct zswap_entry *entry = entries[i];
old = xa_store(swap_zswap_tree(page_swpentry),
swp_offset(page_swpentry),
@@ -1448,7 +1494,7 @@ static ssize_t zswap_store_pages(struct folio *folio,
WARN_ONCE(err != -ENOMEM, "unexpected xarray error: %d\n", err);
zswap_reject_alloc_fail++;
- goto store_failed;
+ goto store_pages_failed;
}
/*
@@ -1489,16 +1535,19 @@ static ssize_t zswap_store_pages(struct folio *folio,
}
compressed_bytes += entry->length;
- continue;
-
-store_failed:
- zpool_free(pool->zpool, entry->handle);
-compress_failed:
- zswap_entry_cache_free(entry);
- return -EINVAL;
}
return compressed_bytes;
+
+store_pages_failed:
+ for (i = 0; i < nr_pages; ++i) {
+ if (!IS_ERR_VALUE(entries[i]->handle))
+ zpool_free(pool->zpool, entries[i]->handle);
+
+ zswap_entry_cache_free(entries[i]);
+ }
+
+ return -EINVAL;
}
bool zswap_store(struct folio *folio)
--
2.27.0
next prev parent reply other threads:[~2024-11-27 22:53 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-27 22:53 [PATCH v1 0/2] Vectorize and simplify zswap_store_page() Kanchana P Sridhar
2024-11-27 22:53 ` [PATCH v1 1/2] mm: zswap: Modified zswap_store_page() to process multiple pages in a folio Kanchana P Sridhar
2024-12-02 19:33 ` Yosry Ahmed
2024-12-03 1:13 ` Sridhar, Kanchana P
2024-12-03 5:34 ` Yosry Ahmed
2024-12-03 21:25 ` Sridhar, Kanchana P
2024-12-03 3:23 ` Chengming Zhou
2024-12-03 4:37 ` Sridhar, Kanchana P
2024-11-27 22:53 ` Kanchana P Sridhar [this message]
2024-11-28 7:00 ` [PATCH v1 2/2] mm: zswap: zswap_store_pages() simplifications for batching Chengming Zhou
2024-12-02 19:32 ` Yosry Ahmed
2024-12-03 1:01 ` Sridhar, Kanchana P
2024-12-03 3:06 ` Chengming Zhou
2024-12-03 4:18 ` Sridhar, Kanchana P
2024-12-03 5:49 ` Yosry Ahmed
2024-12-03 21:28 ` Sridhar, Kanchana P
2024-12-03 0:17 ` Nhat Pham
2024-12-03 1:15 ` Sridhar, Kanchana P
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=20241127225324.6770-3-kanchana.p.sridhar@intel.com \
--to=kanchana.p.sridhar@intel.com \
--cc=21cnbao@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=chengming.zhou@linux.dev \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nphamcs@gmail.com \
--cc=ryan.roberts@arm.com \
--cc=usamaarif642@gmail.com \
--cc=vinodh.gopal@intel.com \
--cc=wajdi.k.feghali@intel.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox