-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Introducing a memory attributes based heap allocator #63014
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introducing a memory attributes based heap allocator #63014
Conversation
|
Wonder if this can be made to work with |
@dcpleung This is using |
tests/subsys/mem_mgmt/mem_attr_heap/boards/qemu_cortex_m3.overlay
Outdated
Show resolved
Hide resolved
|
To clarify my concerns, say we define a memory region like this with the new attribute: It means that the whole region will be used by heap, but the linker script will still just treat it as an empty memory region: So the user could move data into SRAM1 which will give incorrect results but the linker will still be happy. These types of errors could not be made with the previous implementation of shared multi heap. It would be nice if the sram could be partitioned into a sub-region for the heap. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Carles pulled me over. I absolutely love the API.
One nitpick on the old API removal just so we can say that someone mentioned "deprecation" during review.
Not really expert enough to talk much about the DTS layer work, except to parrot @evgeniy-paltsev 's general concern that the memory region specification at the platform layer is high complexity and a little confusing. But that's an area where we can tolerate more complexity, so not sure it's disqualifying? And it's sort of a hard problem anyway: a given allocation is always going to end up matching potentially multiple regions and there isn't always going to be a Correct Choice regardless. Probably best to merge whatever seems straightforward and then tweak as platforms run into difficulty.
lib/os/shared_multi_heap.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pedantry: are we absolutely sure this doesn't have any out-of-tree users? I'll let the experts chime in on whether this needs formal deprecation or not, just calling it out. I personally don't mind the deletion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently we have at least one user (@talih0) so I'll leave that in place so that we don't need to deprecate anything.
|
I like it! |
doc/services/mem_mgmt/index.rst
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It worth to mention here if it is possible to specify multiple DT_MEM_SW_ALLOC* attributes. Like DT_MEM_SW_ALLOC_DMA | DT_MEM_SW_ALLOC_NON_CACHE.
As I understand that wouldn't work (please correct me if I'm wrong) - so we should mention that in the docs and it would be useful to add compile-time assertion against such combination.
Alternatively we can just define DT_MEM_SW_ALLOC* attributes not as a individual bits but as an enum:
-#define ATTR_SW_ALLOC_CACHE BIT(0)
-#define ATTR_SW_ALLOC_NON_CACHE BIT(1)
-#define ATTR_SW_ALLOC_DMA BIT(2)
+#define ATTR_SW_ALLOC_CACHE 1
+#define ATTR_SW_ALLOC_NON_CACHE 2
+#define ATTR_SW_ALLOC_DMA 3There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand that wouldn't work (please correct me if I'm wrong)
It would work. From the allocator prospective DT_MEM_SW_ALLOC_CACHE is different than DT_MEM_SW_ALLOC_CACHE | DT_MEM_SW_ALLOC_DMA, so you can allocate from one region or from the other region depending on the parameter passed to mem_attr_heap_alloc().
I'll add a new test for this case and I'll fix the documentation that indeed is a bit unclear on this point.
Using this new library it is now possible to leverage the memory attribute property 'zephyr,memory-attr' to define and create a set of memory heaps from which the user can allocate memory from with certain attributes / capabilities. When the CONFIG_MEM_ATTR_HEAP option is set, every region marked with one of the memory attributes listed in include/zephyr/dt-bindings/memory-attr/memory-attr-sw.h is added to a pool of memory heaps used for dynamic allocation of memory buffers with certain attributes. Signed-off-by: Carlo Caione <[email protected]>
Add new documentation for the new attribute-based memory allocator. Signed-off-by: Carlo Caione <[email protected]>
Add a new test for the attribute-based memory allocator. Signed-off-by: Carlo Caione <[email protected]>
9f3f9d3
|
Pushed new revision.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refresh +1
| compatible = "mmio-sram"; | ||
| reg = <0x20000000 0x1000>; | ||
| zephyr,memory-attr = <( DT_MEM_NON_CACHEABLE | ATTR_SW_ALLOC_NON_CACHE )>; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ATTR_SW_ALLOC_NON_CACHE should be DT_MEM_SW_ALLOC_NON_CACHE?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huuu, yeah, I'll fix that in a later commit. It would suck to lose all the ACKs to fix spelling errors.
| // Allocate 0x100 bytes of cacheable memory from `mem_cacheable` | ||
| block = mem_attr_heap_alloc(DT_MEM_SW_ALLOC_CACHE, 0x100); | ||
| // Allocate 0x200 bytes of non-cacheable memory aligned to 32 bytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allocate 0x100?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
| * @brief Init the memory pool | ||
| * | ||
| * This must be the first function to be called to initialize the memory pools | ||
| * from all the memory regions with the a software attribute. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "the a software attribute"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
|
@evgeniy-paltsev can you take a look again? |
This is a natural evolution of the work started with #61009
The idea is that it is possible to leverage the memory attribute property
zephyr,memory-attrto define and create a set of memory heaps from which the user can allocate memory from with certain attributes / capabilities.When the
CONFIG_MEM_ATTR_HEAPis set, every region marked with one of the memory attributes listed in ininclude/zephyr/dt-bindings/memory-attr/memory-attr-sw.his added to a pool of memory heaps used for dynamic allocation of memory buffers with certain attributes.Here a non exhaustive list of possible attributes:
For example we can define several memory regions with different attributes and use the appropriate attribute to indicate that it is possible to dynamically allocate memory from those regions:
The user can then dynamically carve memory out of those regions using the provided functions, the library will take care of allocating memory from the correct heap depending on the provided attribute and size:
When several regions are marked with the same attributes, the memory is allocated:
From the regions where the
zephyr,memory-attrproperty has at least the requested property (other attributes can be present as well).Among the regions as at point 1, from the smallest region if there is any unallocated space left for the requested size
If there is not enough space, from the next bigger region able to accommodate the requested size
The following example shows the point 3:
Important
The framework is assuming that the memory regions used to create the heaps are usable by the code and available at init time. The user must take of initializing and setting the memory area before calling
mem_attr_heap_pool_init.That means that the region must be correctly configured in terms of MPU / MMU (if needed) and that an actual heap can be created out of it, for example by leveraging the
zephyr,memory-regionproperty to create a proper linker section to accommodate the heap.