Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

memblock: unpreserve memory in case of error

If there is an error half way through KHO memory preservation, we should
rollback and unpreserve everything that is partially preserved.

[akpm@linux-foundation.org: s/err_no_fdt_page/err_report/ in prepare_kho_fdt(), per Mike]
Link: https://lkml.kernel.org/r/20251101142325.1326536-5-pasha.tatashin@soleen.com
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Suggested-by: Pratyush Yadav <pratyush@kernel.org>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
Cc: Alexander Graf <graf@amazon.com>
Cc: Changyuan Lyu <changyuanl@google.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Simon Horman <horms@kernel.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Zhu Yanjun <yanjun.zhu@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Pasha Tatashin and committed by
Andrew Morton
f5bfd479 36f8f7ef

+67 -24
+67 -24
mm/memblock.c
··· 2445 2445 #define MEMBLOCK_KHO_NODE_COMPATIBLE "memblock-v1" 2446 2446 #define RESERVE_MEM_KHO_NODE_COMPATIBLE "reserve-mem-v1" 2447 2447 2448 - static int __init prepare_kho_fdt(void) 2448 + static int __init reserved_mem_preserve(void) 2449 2449 { 2450 - int err = 0, i; 2451 - struct page *fdt_page; 2452 - void *fdt; 2450 + unsigned int nr_preserved = 0; 2451 + int err; 2453 2452 2454 - fdt_page = alloc_page(GFP_KERNEL); 2455 - if (!fdt_page) 2456 - return -ENOMEM; 2457 - 2458 - fdt = page_to_virt(fdt_page); 2459 - 2460 - err |= fdt_create(fdt, PAGE_SIZE); 2461 - err |= fdt_finish_reservemap(fdt); 2462 - 2463 - err |= fdt_begin_node(fdt, ""); 2464 - err |= fdt_property_string(fdt, "compatible", MEMBLOCK_KHO_NODE_COMPATIBLE); 2465 - for (i = 0; i < reserved_mem_count; i++) { 2453 + for (unsigned int i = 0; i < reserved_mem_count; i++, nr_preserved++) { 2466 2454 struct reserve_mem_table *map = &reserved_mem_table[i]; 2467 2455 struct page *page = phys_to_page(map->start); 2468 2456 unsigned int nr_pages = map->size >> PAGE_SHIFT; 2469 2457 2470 - err |= kho_preserve_pages(page, nr_pages); 2458 + err = kho_preserve_pages(page, nr_pages); 2459 + if (err) 2460 + goto err_unpreserve; 2461 + } 2462 + 2463 + return 0; 2464 + 2465 + err_unpreserve: 2466 + for (unsigned int i = 0; i < nr_preserved; i++) { 2467 + struct reserve_mem_table *map = &reserved_mem_table[i]; 2468 + struct page *page = phys_to_page(map->start); 2469 + unsigned int nr_pages = map->size >> PAGE_SHIFT; 2470 + 2471 + kho_unpreserve_pages(page, nr_pages); 2472 + } 2473 + 2474 + return err; 2475 + } 2476 + 2477 + static int __init prepare_kho_fdt(void) 2478 + { 2479 + struct page *fdt_page; 2480 + void *fdt; 2481 + int err; 2482 + 2483 + fdt_page = alloc_page(GFP_KERNEL); 2484 + if (!fdt_page) { 2485 + err = -ENOMEM; 2486 + goto err_report; 2487 + } 2488 + 2489 + fdt = page_to_virt(fdt_page); 2490 + err = kho_preserve_pages(fdt_page, 1); 2491 + if (err) 2492 + goto err_free_fdt; 2493 + 2494 + err |= fdt_create(fdt, PAGE_SIZE); 2495 + err |= fdt_finish_reservemap(fdt); 2496 + err |= fdt_begin_node(fdt, ""); 2497 + err |= fdt_property_string(fdt, "compatible", MEMBLOCK_KHO_NODE_COMPATIBLE); 2498 + 2499 + for (unsigned int i = 0; !err && i < reserved_mem_count; i++) { 2500 + struct reserve_mem_table *map = &reserved_mem_table[i]; 2501 + 2471 2502 err |= fdt_begin_node(fdt, map->name); 2472 2503 err |= fdt_property_string(fdt, "compatible", RESERVE_MEM_KHO_NODE_COMPATIBLE); 2473 2504 err |= fdt_property(fdt, "start", &map->start, sizeof(map->start)); ··· 2508 2477 err |= fdt_end_node(fdt); 2509 2478 err |= fdt_finish(fdt); 2510 2479 2511 - err |= kho_preserve_folio(page_folio(fdt_page)); 2480 + if (err) 2481 + goto err_unpreserve_fdt; 2512 2482 2513 - if (!err) 2514 - err = kho_add_subtree(MEMBLOCK_KHO_FDT, fdt); 2483 + err = kho_add_subtree(MEMBLOCK_KHO_FDT, fdt); 2484 + if (err) 2485 + goto err_unpreserve_fdt; 2515 2486 2516 - if (err) { 2517 - pr_err("failed to prepare memblock FDT for KHO: %d\n", err); 2518 - put_page(fdt_page); 2519 - } 2487 + err = reserved_mem_preserve(); 2488 + if (err) 2489 + goto err_remove_subtree; 2490 + 2491 + return 0; 2492 + 2493 + err_remove_subtree: 2494 + kho_remove_subtree(fdt); 2495 + err_unpreserve_fdt: 2496 + kho_unpreserve_pages(fdt_page, 1); 2497 + err_free_fdt: 2498 + put_page(fdt_page); 2499 + err_report: 2500 + pr_err("failed to prepare memblock FDT for KHO: %d\n", err); 2520 2501 2521 2502 return err; 2522 2503 }