From aeb4358a52365269e6ca658505a6410ed85570b2 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Fri, 29 Nov 2024 02:26:19 +0100 Subject: [PATCH] s390/boot: Add physmem_alloc() Add physmem_alloc() as a variant of physmem_alloc_or_die() that can return an error instead of triggering a panic on OOM. This allows callers to implement alternative fallback paths. Reviewed-by: Alexander Gordeev Signed-off-by: Vasily Gorbik Signed-off-by: Alexander Gordeev --- arch/s390/boot/boot.h | 2 ++ arch/s390/boot/physmem_info.c | 28 +++++++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h index f26902624650..ce8422d8f9a8 100644 --- a/arch/s390/boot/boot.h +++ b/arch/s390/boot/boot.h @@ -49,6 +49,8 @@ void physmem_free(enum reserved_range_type type); /* for continuous/multiple allocations per type */ unsigned long physmem_alloc_or_die(enum reserved_range_type type, unsigned long size, unsigned long align); +unsigned long physmem_alloc(enum reserved_range_type type, unsigned long size, + unsigned long align, bool die_on_oom); /* for single allocations, 1 per type */ unsigned long physmem_alloc_range(enum reserved_range_type type, unsigned long size, unsigned long align, unsigned long min, unsigned long max, diff --git a/arch/s390/boot/physmem_info.c b/arch/s390/boot/physmem_info.c index 34d310a6d8a5..f585f015abfe 100644 --- a/arch/s390/boot/physmem_info.c +++ b/arch/s390/boot/physmem_info.c @@ -343,8 +343,8 @@ unsigned long physmem_alloc_range(enum reserved_range_type type, unsigned long s return addr; } -unsigned long physmem_alloc_or_die(enum reserved_range_type type, unsigned long size, - unsigned long align) +unsigned long physmem_alloc(enum reserved_range_type type, unsigned long size, + unsigned long align, bool die_on_oom) { struct reserved_range *range = &physmem_info.reserved[type]; struct reserved_range *new_range; @@ -352,18 +352,22 @@ unsigned long physmem_alloc_or_die(enum reserved_range_type type, unsigned long unsigned long addr; addr = __physmem_alloc_range(size, align, 0, physmem_alloc_pos, physmem_alloc_ranges, - &ranges_left, true); + &ranges_left, die_on_oom); + if (!addr) + return 0; /* if not a consecutive allocation of the same type or first allocation */ if (range->start != addr + size) { if (range->end) { - physmem_alloc_pos = __physmem_alloc_range( - sizeof(struct reserved_range), 0, 0, physmem_alloc_pos, - physmem_alloc_ranges, &ranges_left, true); - new_range = (struct reserved_range *)physmem_alloc_pos; + addr = __physmem_alloc_range(sizeof(struct reserved_range), 0, 0, + physmem_alloc_pos, physmem_alloc_ranges, + &ranges_left, true); + new_range = (struct reserved_range *)addr; + addr = __physmem_alloc_range(size, align, 0, addr, ranges_left, + &ranges_left, die_on_oom); + if (!addr) + return 0; *new_range = *range; range->chain = new_range; - addr = __physmem_alloc_range(size, align, 0, physmem_alloc_pos, - ranges_left, &ranges_left, true); } range->end = addr + size; } @@ -373,6 +377,12 @@ unsigned long physmem_alloc_or_die(enum reserved_range_type type, unsigned long return addr; } +unsigned long physmem_alloc_or_die(enum reserved_range_type type, unsigned long size, + unsigned long align) +{ + return physmem_alloc(type, size, align, true); +} + unsigned long get_physmem_alloc_pos(void) { return physmem_alloc_pos; -- 2.25.1