From: Pasha Tatashin <pasha.tatashin@soleen.com>
To: akpm@linux-foundation.org, brauner@kernel.org, corbet@lwn.net,
graf@amazon.com, jgg@ziepe.ca, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org, linux-mm@kvack.org,
masahiroy@kernel.org, ojeda@kernel.org,
pasha.tatashin@soleen.com, pratyush@kernel.org,
rdunlap@infradead.org, rppt@kernel.org, tj@kernel.org,
yanjun.zhu@linux.dev
Subject: [PATCH v9 5/9] test_kho: Unpreserve memory in case of error
Date: Sat, 1 Nov 2025 10:23:21 -0400 [thread overview]
Message-ID: <20251101142325.1326536-6-pasha.tatashin@soleen.com> (raw)
In-Reply-To: <20251101142325.1326536-1-pasha.tatashin@soleen.com>
If there is an error half way through KHO memory preservation, we should
rollback and unpreserve everything that is partially preserved.
Co-developed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
---
lib/test_kho.c | 103 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 73 insertions(+), 30 deletions(-)
diff --git a/lib/test_kho.c b/lib/test_kho.c
index 9f7cfa6ac855..025ea251a186 100644
--- a/lib/test_kho.c
+++ b/lib/test_kho.c
@@ -33,17 +33,28 @@ struct kho_test_state {
unsigned int nr_folios;
struct folio **folios;
phys_addr_t *folios_info;
+ struct kho_vmalloc folios_info_phys;
+ int nr_folios_preserved;
struct folio *fdt;
__wsum csum;
};
static struct kho_test_state kho_test_state;
-static int kho_test_save_data(struct kho_test_state *state, void *fdt)
+static void kho_test_unpreserve_data(struct kho_test_state *state)
+{
+ for (int i = 0; i < state->nr_folios_preserved; i++)
+ kho_unpreserve_folio(state->folios[i]);
+
+ kho_unpreserve_vmalloc(&state->folios_info_phys);
+ vfree(state->folios_info);
+}
+
+static int kho_test_preserve_data(struct kho_test_state *state)
{
- phys_addr_t *folios_info __free(kvfree) = NULL;
struct kho_vmalloc folios_info_phys;
- int err = 0;
+ phys_addr_t *folios_info;
+ int err;
folios_info = vmalloc_array(state->nr_folios, sizeof(*folios_info));
if (!folios_info)
@@ -51,64 +62,98 @@ static int kho_test_save_data(struct kho_test_state *state, void *fdt)
err = kho_preserve_vmalloc(folios_info, &folios_info_phys);
if (err)
- return err;
+ goto err_free_info;
+
+ state->folios_info_phys = folios_info_phys;
+ state->folios_info = folios_info;
for (int i = 0; i < state->nr_folios; i++) {
struct folio *folio = state->folios[i];
unsigned int order = folio_order(folio);
folios_info[i] = virt_to_phys(folio_address(folio)) | order;
-
err = kho_preserve_folio(folio);
if (err)
- break;
+ goto err_unpreserve;
+ state->nr_folios_preserved++;
}
+ return 0;
+
+err_unpreserve:
+ /*
+ * kho_test_unpreserve_data frees folio_info, bail out immediately to
+ * avoid double free
+ */
+ kho_test_unpreserve_data(state);
+ return err;
+
+err_free_info:
+ vfree(folios_info);
+ return err;
+}
+
+static int kho_test_prepare_fdt(struct kho_test_state *state, ssize_t fdt_size)
+{
+ const char compatible[] = KHO_TEST_COMPAT;
+ unsigned int magic = KHO_TEST_MAGIC;
+ void *fdt = folio_address(state->fdt);
+ int err;
+
+ err = fdt_create(fdt, fdt_size);
+ err |= fdt_finish_reservemap(fdt);
+ err |= fdt_begin_node(fdt, "");
+ err |= fdt_property(fdt, "compatible", compatible, sizeof(compatible));
+ err |= fdt_property(fdt, "magic", &magic, sizeof(magic));
+
err |= fdt_begin_node(fdt, "data");
err |= fdt_property(fdt, "nr_folios", &state->nr_folios,
sizeof(state->nr_folios));
- err |= fdt_property(fdt, "folios_info", &folios_info_phys,
- sizeof(folios_info_phys));
+ err |= fdt_property(fdt, "folios_info", &state->folios_info_phys,
+ sizeof(state->folios_info_phys));
err |= fdt_property(fdt, "csum", &state->csum, sizeof(state->csum));
err |= fdt_end_node(fdt);
- if (!err)
- state->folios_info = no_free_ptr(folios_info);
+ err |= fdt_end_node(fdt);
+ err |= fdt_finish(fdt);
return err;
}
-static int kho_test_prepare_fdt(struct kho_test_state *state)
+static int kho_test_preserve(struct kho_test_state *state)
{
- const char compatible[] = KHO_TEST_COMPAT;
- unsigned int magic = KHO_TEST_MAGIC;
ssize_t fdt_size;
- int err = 0;
- void *fdt;
+ int err;
fdt_size = state->nr_folios * sizeof(phys_addr_t) + PAGE_SIZE;
state->fdt = folio_alloc(GFP_KERNEL, get_order(fdt_size));
if (!state->fdt)
return -ENOMEM;
- fdt = folio_address(state->fdt);
-
- err |= kho_preserve_folio(state->fdt);
- err |= fdt_create(fdt, fdt_size);
- err |= fdt_finish_reservemap(fdt);
+ err = kho_preserve_folio(state->fdt);
+ if (err)
+ goto err_free_fdt;
- err |= fdt_begin_node(fdt, "");
- err |= fdt_property(fdt, "compatible", compatible, sizeof(compatible));
- err |= fdt_property(fdt, "magic", &magic, sizeof(magic));
- err |= kho_test_save_data(state, fdt);
- err |= fdt_end_node(fdt);
+ err = kho_test_preserve_data(state);
+ if (err)
+ goto err_unpreserve_fdt;
- err |= fdt_finish(fdt);
+ err = kho_test_prepare_fdt(state, fdt_size);
+ if (err)
+ goto err_unpreserve_data;
err = kho_add_subtree(KHO_TEST_FDT, folio_address(state->fdt));
if (err)
- folio_put(state->fdt);
+ goto err_unpreserve_data;
+ return 0;
+
+err_unpreserve_data:
+ kho_test_unpreserve_data(state);
+err_unpreserve_fdt:
+ kho_unpreserve_folio(state->fdt);
+err_free_fdt:
+ folio_put(state->fdt);
return err;
}
@@ -174,14 +219,12 @@ static int kho_test_save(void)
if (err)
goto err_free_folios;
- err = kho_test_prepare_fdt(state);
+ err = kho_test_preserve(state);
if (err)
goto err_free_folios;
return 0;
-err_free_fdt:
- folio_put(state->fdt);
err_free_folios:
kvfree(folios);
return err;
--
2.51.1.930.gacf6e81ea2-goog
next prev parent reply other threads:[~2025-11-01 14:23 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-01 14:23 [PATCH v9 0/9] liveupdate: Rework KHO for in-kernel users Pasha Tatashin
2025-11-01 14:23 ` [PATCH v9 1/9] kho: make debugfs interface optional Pasha Tatashin
2025-11-07 6:03 ` Zhu Yanjun
2025-11-07 12:00 ` Pasha Tatashin
2025-11-07 12:02 ` Pasha Tatashin
2025-11-07 23:35 ` Yanjun.Zhu
2025-11-08 18:13 ` Pasha Tatashin
2025-11-10 0:20 ` Zhu Yanjun
2025-11-10 13:16 ` Pratyush Yadav
2025-11-10 15:26 ` Pasha Tatashin
2025-11-11 4:11 ` Zhu Yanjun
2025-11-11 15:26 ` Pasha Tatashin
2025-11-13 1:41 ` Yanjun.Zhu
2025-11-13 2:11 ` Yanjun.Zhu
2025-11-13 19:59 ` Pasha Tatashin
2025-11-13 20:07 ` Yanjun.Zhu
2025-11-13 19:55 ` Yanjun.Zhu
2025-11-13 20:10 ` Pasha Tatashin
2025-11-13 20:13 ` Pasha Tatashin
2025-11-13 20:28 ` Yanjun.Zhu
2025-11-01 14:23 ` [PATCH v9 2/9] kho: drop notifiers Pasha Tatashin
2025-11-06 8:41 ` kernel test robot
2025-11-06 21:46 ` Pasha Tatashin
2025-11-06 22:14 ` Pasha Tatashin
2025-11-01 14:23 ` [PATCH v9 3/9] kho: add interfaces to unpreserve folios, page ranges, and vmalloc Pasha Tatashin
2025-11-03 18:05 ` Pratyush Yadav
2025-11-01 14:23 ` [PATCH v9 4/9] memblock: Unpreserve memory in case of error Pasha Tatashin
2025-11-02 6:51 ` Mike Rapoport
2025-11-05 10:26 ` Pratyush Yadav
2025-11-01 14:23 ` Pasha Tatashin [this message]
2025-11-01 14:23 ` [PATCH v9 6/9] kho: don't unpreserve memory during abort Pasha Tatashin
2025-11-05 10:28 ` Pratyush Yadav
2025-11-01 14:23 ` [PATCH v9 7/9] liveupdate: kho: move to kernel/liveupdate Pasha Tatashin
2025-11-06 7:21 ` kernel test robot
2025-11-07 22:23 ` Andrew Morton
2025-11-08 18:01 ` Pasha Tatashin
2025-11-01 14:23 ` [PATCH v9 8/9] MAINTAINERS: update KHO maintainers Pasha Tatashin
2025-11-01 16:36 ` Mike Rapoport
2025-11-01 14:23 ` [PATCH v9 9/9] liveupdate: kho: Use %pe format specifier for error pointer printing Pasha Tatashin
2025-11-01 19:45 ` Zhu Yanjun
2025-11-02 6:59 ` Mike Rapoport
2025-11-03 12:59 ` Pratyush Yadav
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=20251101142325.1326536-6-pasha.tatashin@soleen.com \
--to=pasha.tatashin@soleen.com \
--cc=akpm@linux-foundation.org \
--cc=brauner@kernel.org \
--cc=corbet@lwn.net \
--cc=graf@amazon.com \
--cc=jgg@ziepe.ca \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=masahiroy@kernel.org \
--cc=ojeda@kernel.org \
--cc=pratyush@kernel.org \
--cc=rdunlap@infradead.org \
--cc=rppt@kernel.org \
--cc=tj@kernel.org \
--cc=yanjun.zhu@linux.dev \
/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