lib: sbi: Heap improvements for SMMTT
v4 cover lib: sbi: Heap improvements for SMMTT
This patch series includes two changes to the SBI heap implementation, primarily to enable future work on the SMMTT implementation. First, it enables allocations from multiple independent heaps on separate memory regions. Then, it adds a simple implementation for sbi_memalign for use in allocating aligned memory.
See the individual commit messages in this series for more technical details.
v4:
- Rename sbi_memalign{_from} -> sbi_aligned_alloc{_from}
- Miscellaneous code format changes
v3:
- Add missing Signed-off-by lines
- Rename struct heap_control -> struct sbi_heap_control
- Make various functions static inline in sbi_heap.h
- Fix previously incorrect sbi_memalign() implementation
Gregor Haas (3):
lib: sbi: Support multiple heaps
lib: sbi: Allocate from beginning of heap blocks
lib: sbi: Implement aligned memory allocators
include/sbi/sbi_heap.h | 66 +++++++++++-- lib/sbi/sbi_heap.c | 204 +++++++++++++++++++++++++++++------------ 2 files changed, 204 insertions(+), 66 deletions(-)
Signature · 1 line
2.45.2
PATCH v4 1/3 lib: sbi: Support multiple heaps
The upcoming SMMTT implementation will require some larger contiguous memory regions for the memory tracking tables. We plan to specify the memory region for these tables as a reserved-memory node in the device tree, and then dynamically allocate individual tables out of this region. These changes to the SBI heap allocator will allow us to explicitly create and allocate from a dedicated heap tied to the table memory region.
--- include/sbi/sbi_heap.h | 57 +++++++++++++++++-- lib/sbi/sbi_heap.c | 122 +++++++++++++++++++++++------------------ 2 files changed, 119 insertions(+), 60 deletions(-)
include/sbi/sbi_heap.h +51 -6
@@ -12,16 +12,32 @@#include <sbi/sbi_types.h> +/* Opaque declaration of heap control struct */ +struct sbi_heap_control ; + +/* Global heap control structure */ +extern struct sbi_heap_control global_hpctrl; +/* Alignment of heap base address and size */ #define HEAP_BASE_ALIGN 1024struct sbi_scratch ;/** Allocate from heap area */ -void *sbi_malloc (size_t size); +void *sbi_malloc_from (struct sbi_heap_control *hpctrl,size_t size); + +static inline void *sbi_malloc (size_t size) +{ +return sbi_malloc_from (&global_hpctrl, size); +}/** Zero allocate from heap area */ -void *sbi_zalloc (size_t size); +void *sbi_zalloc_from (struct sbi_heap_control *hpctrl,size_t size); + +static inline void *sbi_zalloc (size_t size) +{ +return sbi_zalloc_from (&global_hpctrl, size); +}/** Allocate array from heap area */ static inline void *sbi_calloc (size_t nitems,size_t size)
@@ -29,19 +45,48 @@ static inline void *sbi_calloc(size_t nitems, size_t size)return sbi_zalloc (nitems * size); } +static inline void *sbi_calloc_from (struct sbi_heap_control *hpctrl, +size_t nitems,size_t size) +{ +return sbi_zalloc_from (hpctrl, nitems * size); +} +/** Free-up to heap area */ -void sbi_free (void *ptr); +void sbi_free_from (struct sbi_heap_control *hpctrl,void *ptr); + +static inline void sbi_free (void *ptr) +{ +return sbi_free_from (&global_hpctrl, ptr); +}/** Amount (in bytes) of free space in the heap area */ -unsigned long sbi_heap_free_space (void ); +unsigned long sbi_heap_free_space_from (struct sbi_heap_control *hpctrl); + +static inline unsigned long sbi_heap_free_space (void ) +{ +return sbi_heap_free_space_from (&global_hpctrl); +}/** Amount (in bytes) of used space in the heap area */ -unsigned long sbi_heap_used_space (void ); +unsigned long sbi_heap_used_space_from (struct sbi_heap_control *hpctrl); + +static inline unsigned long sbi_heap_used_space (void ) +{ +return sbi_heap_used_space_from (&global_hpctrl); +}/** Amount (in bytes) of reserved space in the heap area */ -unsigned long sbi_heap_reserved_space (void ); +unsigned long sbi_heap_reserved_space_from (struct sbi_heap_control *hpctrl); + +static inline unsigned long sbi_heap_reserved_space (void ) +{ +return sbi_heap_reserved_space_from (&global_hpctrl); +}/** Initialize heap area */ int sbi_heap_init (struct sbi_scratch *scratch); +int sbi_heap_init_new (struct sbi_heap_control *hpctrl,unsigned long base, +unsigned long size); +int sbi_heap_alloc_new (struct sbi_heap_control **hpctrl);#endif
lib/sbi/sbi_heap.c +68 -54
236 lines not on this page · raw message
Signature · 1 line
2.45.2
PATCH v4 2/3 lib: sbi: Allocate from beginning of heap blocks
In reply to Gregor HaasIn the next commit, we'll add a new sbi_memalign() function. In order to allocate aligned memory, we'll sometimes need to allocate from the middle of a heap block, effectively splitting it in two. Allocating from the beginning of a heap block in the nonaligned case more closely matches this behavior, reducing the complexity of understanding the heap implementation.
--- lib/sbi/sbi_heap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
lib/sbi/sbi_heap.c +2 -1
@@ -63,8 +63,9 @@ void *sbi_malloc_from(struct sbi_heap_control *hpctrl, size_t size) n =sbi_list_first_entry (&hpctrl->free_node_list, struct heap_node, head);sbi_list_del (&n->head); - n->addr = np->addr + np->size - size; + n->addr = np->addr; n->size = size; + np->addr += size; np->size -= size;sbi_list_add_tail (&n->head, &hpctrl->used_space_list); ret = (void *)n->addr;
Signature · 1 line
2.45.2
PATCH v4 3/3 lib: sbi: Implement aligned memory allocators
In reply to Gregor HaasThis change adds a simple implementation of sbi_aligned_alloc(), for future use in allocating aligned memory for SMMTT tables.
--- include/sbi/sbi_heap.h | 9 +++++ lib/sbi/sbi_heap.c | 75 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 6 deletions(-)
include/sbi/sbi_heap.h +9 -0
@@ -31,6 +31,15 @@ static inline void *sbi_malloc(size_t size)return sbi_malloc_from (&global_hpctrl, size); } +/** Allocate aligned from heap area */ +void *sbi_aligned_alloc_from (struct sbi_heap_control *hpctrl, +size_t alignment,size_t size); + +static inline void *sbi_aligned_alloc (size_t alignment,size_t size) +{ +return sbi_aligned_alloc_from (&global_hpctrl, alignment, size); +} +/** Zero allocate from heap area */ void *sbi_zalloc_from (struct sbi_heap_control *hpctrl,size_t size);
lib/sbi/sbi_heap.c +69 -6
107 lines not on this page · raw message
Signature · 1 line
2.45.2
PATCH v4 3/3 lib: sbi: Implement aligned memory allocators
Quoted 5 lines · On Fri, Aug 9, 2024 at 8:46?AM Gregor Haas <[email protected]> wrote:
This change adds a simple implementation of
sbi_aligned_alloc(), for future use in allocating aligned memory for SMMTT tables.Signed-off-by Gregor Haas <[email protected]>
LGTM.
Regards,
Anup
Quoted 141 lines
--- include/sbi/sbi_heap.h | 9 +++++ lib/sbi/sbi_heap.c | 75 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 6 deletions(-)include/sbi/sbi_heap.h +9
-0@@ -31,6 +31,15 @@ static inline void *sbi_malloc(size_t size)return sbi_malloc_from (&global_hpctrl, size); } +/** Allocate aligned from heap area */ +void *sbi_aligned_alloc_from (struct sbi_heap_control *hpctrl, +size_t alignment,size_t size); + +static inline void *sbi_aligned_alloc (size_t alignment,size_t size) +{ +return sbi_aligned_alloc_from (&global_hpctrl, alignment, size); +} +/** Zero allocate from heap area */ void *sbi_zalloc_from (struct sbi_heap_control *hpctrl,size_t size);lib/sbi/sbi_heap.c +69
-7@@ -37,27 +37,67 @@ struct sbi_heap_control {struct sbi_heap_control global_hpctrl; -void *sbi_malloc_from (struct sbi_heap_control *hpctrl,size_t size) +static void *alloc_with_align (struct sbi_heap_control *hpctrl, +size_t align,size_t size) {void *ret =NULL ; -struct heap_node *n, *np; +struct heap_node *n, *np, *rem; +unsigned long lowest_aligned; +size_t pad;if (!size)return NULL ; - size +=HEAP_ALLOC_ALIGN -1 ; - size &= ~((unsigned long )HEAP_ALLOC_ALIGN -1 ); + size += align -1 ; + size &= ~((unsigned long )align -1 );spin_lock (&hpctrl->lock); np =NULL ;sbi_list_for_each_entry (n, &hpctrl->free_space_list, head) { -if (size <= n->size) { + lowest_aligned =ROUNDUP (n->addr, align); + pad = lowest_aligned - n->addr; + +if (size + pad <= n->size) { np = n;break ; } } -if (np) { +if (!np) + goto out; + +if (pad) { +if (sbi_list_empty (&hpctrl->free_node_list)) { + goto out; + } + + n =sbi_list_first_entry (&hpctrl->free_node_list, + struct heap_node, head); +sbi_list_del (&n->head); + +if ((size + pad < np->size) && + !sbi_list_empty (&hpctrl->free_node_list)) { + rem =sbi_list_first_entry (&hpctrl->free_node_list, + struct heap_node, head); +sbi_list_del (&rem->head); + rem->addr = np->addr + (size + pad); + rem->size = np->size - (size + pad); +sbi_list_add_tail (&rem->head, + &hpctrl->free_space_list); + }else if (size + pad != np->size) { +/* Can't allocate, return n */ +sbi_list_add (&n->head, &hpctrl->free_node_list); + ret =NULL ; + goto out; + } + + n->addr = lowest_aligned; + n->size = size; +sbi_list_add_tail (&n->head, &hpctrl->used_space_list); + + np->size = pad; + ret = (void *)n->addr; + }else {if ((size < np->size) && !sbi_list_empty (&hpctrl->free_node_list)) { n = sbi_list_first_entry(&hpctrl->free_node_list,@@ -76,11 +116,34 @@ void *sbi_malloc_from(struct sbi_heap_control *hpctrl, size_t size) } } +out:spin_unlock (&hpctrl->lock);return ret; } +void *sbi_malloc_from (struct sbi_heap_control *hpctrl,size_t size) +{ +return alloc_with_align (hpctrl,HEAP_ALLOC_ALIGN , size); +} + +void *sbi_aligned_alloc_from (struct sbi_heap_control *hpctrl, +size_t alignment,size_t size) +{ +if (alignment <HEAP_ALLOC_ALIGN ) + alignment =HEAP_ALLOC_ALIGN ; + +/* Make sure alignment is power of two */ +if ((alignment & (alignment -1 )) !=0 ) +return NULL ; + +/* Make sure size is multiple of alignment */ +if (size % alignment !=0 ) +return NULL ; + +return alloc_with_align (hpctrl, alignment, size); +} +void *sbi_zalloc_from (struct sbi_heap_control *hpctrl,size_t size) {void *ret =sbi_malloc_from (hpctrl, size); --2.45.2
Anup Patel
Appliedv4 cover lib: sbi: Heap improvements for SMMTT
In reply to Gregor HaasQuoted 18 lines · On Fri, Aug 9, 2024 at 8:46?AM Gregor Haas <[email protected]> wrote:
This patch series includes two changes to the SBI heap implementation, primarily to enable future work on the SMMTT implementation. First, it enables allocations from multiple independent heaps on separate memory regions. Then, it adds a simple implementation for
sbi_memalignfor use in allocating aligned memory.See the individual commit messages in this series for more technical details.
v4:
- Rename sbi_memalign{_from} -> sbi_aligned_alloc{_from}
- Miscellaneous code format changesv3:
- Add missing Signed-off-by lines
- Rename structheap_control-> structsbi_heap_control
- Make various functions static inline insbi_heap.h
- Fix previously incorrectsbi_memalign()implementation
Quoted 4 lines
Gregor Haas (3):
lib: sbi: Support multiple heaps
lib: sbi: Allocate from beginning of heap blocks
lib: sbi: Implement aligned memory allocators
Applied this series to the riscv/opensbi repo.
Thanks,
Anup
Quoted 8 lines
include/sbi/sbi_heap.h | 66 +++++++++++-- lib/sbi/sbi_heap.c | 204 +++++++++++++++++++++++++++++------------ 2 files changed, 204 insertions(+), 66 deletions(-)--
2.45.2