
Hi Sughosh,
On Thu, 4 Jul 2024 at 08:36, Sughosh Ganu sughosh.ganu@linaro.org wrote:
The current LMB API's for allocating and reserving memory use a per-caller based memory view. Memory allocated by a caller can then be overwritten by another caller. Make these allocations and reservations persistent using the alloced list data structure.
Two alloced lists are declared -- one for the available(free) memory, and one for the used memory. Once full, the list can then be extended at runtime.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V1:
- Use alloced list structure for the available and reserved memory lists instead of static arrays.
- Corresponding changes in the code made as a result of the above change.
- Rename the reserved memory list as 'used'.
include/lmb.h | 77 +++-------- lib/lmb.c | 346 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 224 insertions(+), 199 deletions(-)
diff --git a/include/lmb.h b/include/lmb.h index 99fcf5781f..27cdb18c37 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -24,78 +24,18 @@ enum lmb_flags { };
/**
- struct lmb_property - Description of one region.
*/
- struct lmb_region - Description of one region.
- @base: Base address of the region.
- @size: Size of the region
- @flags: memory region attributes
-struct lmb_property { +struct lmb_region { phys_addr_t base; phys_size_t size; enum lmb_flags flags; };
-/*
- For regions size management, see LMB configuration in KConfig
- all the #if test are done with CONFIG_LMB_USE_MAX_REGIONS (boolean)
- case 1. CONFIG_LMB_USE_MAX_REGIONS is defined (legacy mode)
=> CONFIG_LMB_MAX_REGIONS is used to configure the region size,
directly in the array lmb_region.region[], with the same
configuration for memory and reserved regions.
- case 2. CONFIG_LMB_USE_MAX_REGIONS is not defined, the size of each
region is configurated *independently* with
=> CONFIG_LMB_MEMORY_REGIONS: struct lmb.memory_regions
=> CONFIG_LMB_RESERVED_REGIONS: struct lmb.reserved_regions
lmb_region.region is only a pointer to the correct buffer,
initialized in lmb_init(). This configuration is useful to manage
more reserved memory regions with CONFIG_LMB_RESERVED_REGIONS.
- */
-/**
- struct lmb_region - Description of a set of region.
- @cnt: Number of regions.
- @max: Size of the region array, max value of cnt.
- @region: Array of the region properties
- */
-struct lmb_region {
unsigned long cnt;
unsigned long max;
-#if IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS)
struct lmb_property region[CONFIG_LMB_MAX_REGIONS];
-#else
struct lmb_property *region;
-#endif -};
-/**
- struct lmb - Logical memory block handle.
- Clients provide storage for Logical memory block (lmb) handles.
- The content of the structure is managed by the lmb library.
- A lmb struct is initialized by lmb_init() functions.
- The lmb struct is passed to all other lmb APIs.
- @memory: Description of memory regions.
- @reserved: Description of reserved regions.
- @memory_regions: Array of the memory regions (statically allocated)
- @reserved_regions: Array of the reserved regions (statically allocated)
- */
-struct lmb {
struct lmb_region memory;
struct lmb_region reserved;
-#if !IS_ENABLED(CONFIG_LMB_USE_MAX_REGIONS)
struct lmb_property memory_regions[CONFIG_LMB_MEMORY_REGIONS];
struct lmb_property reserved_regions[CONFIG_LMB_RESERVED_REGIONS];
-#endif -};
-void lmb_init_and_reserve(struct bd_info *bd, void *fdt_blob); -void lmb_init_and_reserve_range(phys_addr_t base, phys_size_t size,
void *fdt_blob);
long lmb_add(phys_addr_t base, phys_size_t size); long lmb_reserve(phys_addr_t base, phys_size_t size); /** @@ -134,6 +74,19 @@ void board_lmb_reserve(void); void arch_lmb_reserve(void); void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align);
+/**
- lmb_mem_regions_init() - Initialise the LMB memory
- Initialise the LMB subsystem related data structures. There are two
- alloced lists that are initialised, one for the free memory, and one
- for the used memory.
- Initialise the two lists as part of board init.
- Return: 0 if OK, -ve on failure.
- */
+int lmb_mem_regions_init(void);
#endif /* __KERNEL__ */
#endif /* _LINUX_LMB_H */ diff --git a/lib/lmb.c b/lib/lmb.c index 80945e3cae..a46bc8a7a3 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -6,6 +6,7 @@
- Copyright (C) 2001 Peter Bergner.
*/
+#include <alist.h> #include <efi_loader.h> #include <image.h> #include <mapmem.h> @@ -15,24 +16,30 @@
#include <asm/global_data.h> #include <asm/sections.h> +#include <linux/kernel.h>
DECLARE_GLOBAL_DATA_PTR;
#define LMB_ALLOC_ANYWHERE 0 +#define LMB_ALIST_INITIAL_SIZE 4
-static void lmb_dump_region(struct lmb_region *rgn, char *name) +struct alist lmb_free_mem; +struct alist lmb_used_mem;
I think these should be in a struct, e.g. struct lmb, allocated with malloc() and pointed to by gd->lmb so we can avoid making the tests destructive, and allow use of lmb in SPL. There is a arch_reset_for_test() which can reset the lmb back to its original state, or perhaps just swap the pointer for tests.
I know this series is already long, but this patch seems to do quite a bit. Perhaps it could be split into two?
Regards, Simon