Skip to content

[RFC] allocator: unify alloc API - #1155

Closed
RanderWang wants to merge 2 commits into
thesofproject:masterfrom
RanderWang:memory_unify
Closed

RanderWang wants to merge 2 commits into
thesofproject:masterfrom
RanderWang:memory_unify

Conversation

@RanderWang

@RanderWang RanderWang commented Mar 20, 2019 •

Copy link
Copy Markdown
Collaborator

Rmalloc and rzalloc would waste much memory for allocation of big
chunk of memory. For example, if allocation size of 600 is requested,
memory sized 1024 would be allocated.Now refine the algorithm: First
remove the rballoc function and user should call rmalloc and rzalloc to
allocate memory. Second, if the allocation size > HEAP_BUFFER_SIZE,
it would be allocated from buffer heap, or it would be done as usual. And
if it is not supported by system heap, rt heap, it would be allocated from
buffer heap.

The idea is derived from #1128.

This fixes #1128

@RanderWang RanderWang changed the title allocator: unify alloc API [RFC] allocator: unify alloc API Mar 20, 2019

@jajanusz jajanusz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need [RFC] tag in commit messages, it's good enough to have it in PR title

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this name be less generic ? To indicate it's related to HEAP, or even just for non-rballoc

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RanderWang This will be platform and heap config specific. Use the buffer heap block size here.

HEAP_BUFFER_BLOCK_SIZE

You should also remodel the heap configs and remove any block sizes above HEAP_BUFFER_BLOCK_SIZE e.g.

/* Heap section sizes for module pool */
#define HEAP_RT_COUNT8		0
#define HEAP_RT_COUNT16		48
#define HEAP_RT_COUNT32		48
#define HEAP_RT_COUNT64		32
#define HEAP_RT_COUNT128	32
#define HEAP_RT_COUNT256	32
#define HEAP_RT_COUNT512	4 << remove since > than buffer block size.
#define HEAP_RT_COUNT1024	4 << remove

Removing the large block frees up 6k which can either be added to this heap as smaller blocks or automatically to the buffer heap. I would add a 48, 96, 192 block sizes with the extra 6k as this makes the memory more granular.

/* Heap section sizes for system runtime heap */
#define HEAP_SYS_RT_COUNT64	64
#define HEAP_SYS_RT_COUNT512	8 << remove
#define HEAP_SYS_RT_COUNT1024	4 << remove

This saves 8k, which again can be reallocated where best needed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lgirdwood Now the algorithm is:

   if (size >= 384)
          rballoc
   else
          _malloc

So HEAP_RT_COUNT384 should be added to make HEAP_RT to support allocation size < 384 && size > 256

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lgirdwood , I find that cache line size is 64byte in xtensa core, I would drop 48 and 96

Comment thread src/include/sof/alloc.h Resolved
Comment thread src/include/sof/alloc.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention is that rballoc will just be static.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I will update it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RanderWang This will be platform and heap config specific. Use the buffer heap block size here.

HEAP_BUFFER_BLOCK_SIZE

You should also remodel the heap configs and remove any block sizes above HEAP_BUFFER_BLOCK_SIZE e.g.

/* Heap section sizes for module pool */
#define HEAP_RT_COUNT8		0
#define HEAP_RT_COUNT16		48
#define HEAP_RT_COUNT32		48
#define HEAP_RT_COUNT64		32
#define HEAP_RT_COUNT128	32
#define HEAP_RT_COUNT256	32
#define HEAP_RT_COUNT512	4 << remove since > than buffer block size.
#define HEAP_RT_COUNT1024	4 << remove

Removing the large block frees up 6k which can either be added to this heap as smaller blocks or automatically to the buffer heap. I would add a 48, 96, 192 block sizes with the extra 6k as this makes the memory more granular.

/* Heap section sizes for system runtime heap */
#define HEAP_SYS_RT_COUNT64	64
#define HEAP_SYS_RT_COUNT512	8 << remove
#define HEAP_SYS_RT_COUNT1024	4 << remove

This saves 8k, which again can be reallocated where best needed.

@RanderWang

Copy link
Copy Markdown
Collaborator Author

You don't need [RFC] tag in commit messages, it's good enough to have it in PR title

Thanks! I will update my PR

@RanderWang

Copy link
Copy Markdown
Collaborator Author

update PR.
(1) add block size of 192 and 384
(2) refine block size according to cache line size, delete small block of 16, 32
(3) change _balloc, _malloc and _zalloc to static function

@RanderWang

Copy link
Copy Markdown
Collaborator Author

Sorry, I will refine code for host build tomorrow.

@lgirdwood lgirdwood left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know 48, 96 is not aligned on a single cache line, but we will waste a lot of memory on systems like Baytrail that have very limited DRAM.

Comment thread src/include/sof/alloc.h Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you adding 384 when it's the buffer block size ?

@RanderWang RanderWang Mar 22, 2019 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the algorithm is:

   if (size >= 384)
        ptr =  rballoc
   else
        ptr = _malloc

    if (!ptr)
        ptr = rballoc

Without 384 block, for the allocation 256 < size < 384, it can't be supported by _malloc but wastes cpu time in _malloc. So I add this to fix it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is opportunity now (since we have save memory by deleting 512 and 1024 blocks) to add more step sizes here. You could also add 320 block size. It does need a macro though for your largest block size before rballoc blocks for the logic statement above.

@RanderWang

Copy link
Copy Markdown
Collaborator Author

I know 48, 96 is not aligned on a single cache line, but we will waste a lot of memory on systems like Baytrail that have very limited DRAM.

Yes, I will refine the block size on BYT and BDW

@RanderWang

Copy link
Copy Markdown
Collaborator Author

update my PR
(1) refine the definition of alloc api
(2) refine the block size on BYT and HSW

Thanks!

Comment thread src/lib/alloc.c Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best to just return _balloc(zone, caps, bytes) here as it saves the extra indentation below.

Comment thread src/lib/alloc.c Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is opportunity now (since we have save memory by deleting 512 and 1024 blocks) to add more step sizes here. You could also add 320 block size. It does need a macro though for your largest block size before rballoc blocks for the logic statement above.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you making block 256 count smaller ?

@RanderWang RanderWang Mar 25, 2019 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lgirdwood This is the summary of allocation on BYT with nocodec. So I decreased the size of 256. Do you prefer to change the block number of other size ?

841     heap: runtime status
815      heap: 0xff317080 size 17664 blocks 8 caps 0x61
817       used 8704 free 8960
825       block 1 base 0xff317380 size 32
828        count 48 free 48
825       block 2 base 0xff317980 size 64
828        count 32 free 32
825       block 3 base 0xff318180 size 128
828        count 16 free 3 
825       block 4 base 0xff318980 size 192
828        count 16 free 5 
825       block 5 base 0xff319580 size 256
828        count 24 free 8 
825       block 6 base 0xff31ad80 size 320
828        count 2 free 1  
825       block 7 base 0xff31b280 size 384
828        count 2 free 2

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RanderWang why do you have blocks defined for 384 ? when this is the buffer block size ? i.e. it's not needed as code will use buffer heap here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lgirdwood we have got agreement at this 4 days ago, right ?

 lgirdwood 4 days ago Member

Why are you adding 384 when it's the buffer block size ?
@RanderWang
RanderWang 4 days ago •
Author Member

Now the algorithm is:

   if (size >= 384)
        ptr =  rballoc
   else
        ptr = _malloc

    if (!ptr)
        ptr = rballoc

Without 384 block, for the allocation 256 < size < 384, it can't be supported by _malloc but wastes
 cpu time in _malloc. So I add this to fix it
@lgirdwood
lgirdwood 4 days ago Member

There is opportunity now (since we have save memory by deleting 512 and 1024 blocks) to add 
more step sizes here. You could also add 320 block size. It does need a macro though for your 
largest block size before rballoc blocks for the logic statement above.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RanderWang I mean you dont need to add any blocks of size 384 to the non buffer heap map since all blocks of 384 size will be in buffer heap.

@RanderWang RanderWang Mar 27, 2019 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lgirdwood yes, but I talk about allocation size (.eg 360 )< 384 and > 320. For this kind of allocation, It will be not allocated from buffer heap but it is not supported by other non buffer heap without 384 included. block of sized 384 is for allocation size < 384 && > 320

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is there is a gap between 320 and 384

---------------                        -----------------------
               320                     384

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, now I see to fill this gap, but it would be better to remove

#define HEAP_RT_LP_COUNT384		4

and catch all allocations above the largest block size (in this case 320) to us the buffer heap.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked there is no free block of 384 sized on apollolake and whiskylake, icelake, so I will remove 384 on Baytray and haswell only. Thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RanderWang have you pushed the updated branch, I'm still seeing block size 384 for some heaps (not all)

@RanderWang

Copy link
Copy Markdown
Collaborator Author

update my PR
(1) add 320 sized block
(2) refine rballoc

@RanderWang

Copy link
Copy Markdown
Collaborator Author

update my PR. Remove 384 sized block on baytrial and haswell

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RanderWang have you pushed the updated branch, I'm still seeing block size 384 for some heaps (not all)

@RanderWang
RanderWang force-pushed the memory_unify branch 3 times, most recently from b74faa5 to 3bbd6e5 Compare March 29, 2019 06:01
@lgirdwood

Copy link
Copy Markdown
Member

@tlauda I was hoping to wait til after v1.3, but due to IPC issue we can merge when conflicts are resolved. @RanderWang

Rmalloc and rzalloc would waste much memory for allocation of big
chunk of memory. Now refine the algorithm: First remove the rballoc
function and user should call rmalloc and rzalloc to allocate memory.
Second, if the allocation size > HEAP_BUFFER_SIZE, it would be allocated
from buffer heap, or it would be done as usual. And if it is not supported
by system heap, rt heap, it would be allocated from buffer heap.

Signed-off-by: Rander Wang <rander.wang@linux.intel.com>
@RanderWang
RanderWang force-pushed the memory_unify branch 2 times, most recently from d594b17 to d3d0068 Compare April 22, 2019 07:10
Change block size of 512 and 1024 to 192 and 320 to save memory.
For APL and later chips, cache line size is 64byte in xtensa core.
For BYT and HSW, cpu cache is not supported. This PR refines the
block size to be aligned to cache line size on supported chips.

Now sys_runtime and runtime heap don't support allcation size
bigger than 320. Buffer heap would support it.

Signed-off-by: Rander Wang <rander.wang@linux.intel.com>
@RanderWang

Copy link
Copy Markdown
Collaborator Author

@tlauda I rebased my PR and get one CI failed. I checked the log but didn't find any hint. Could do you help to check it ? thanks!

@tlauda

tlauda commented Apr 22, 2019

Copy link
Copy Markdown
Contributor

@zrombel Could you take a look?

@tlauda
tlauda requested a review from lgirdwood May 6, 2019 09:55
@lgirdwood

Copy link
Copy Markdown
Member

@RanderWang this is pending for 1.4, but in the meantime it's conflicting

@zrombel

zrombel commented May 6, 2019

Copy link
Copy Markdown

This PR is not ready for merging. PR is causing DSP panic in random python tests on all platforms especially in tests:
TestPtpSimpleStreamOperations, TestPtpParallelExternal and DMIC tests.

@RanderWang

Copy link
Copy Markdown
Collaborator Author

ok, I will test and refine it after 1.3 released

TEST_BULK, "rballoc_dma"),
TEST_CASE(256, RZONE_BUFFER, SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, 2,
TEST_BULK, "rballoc_dma"),
TEST_CASE(2048, RZONE_BUFFER, SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, 100,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot just delete those - marked test case is crucial for finding if we free memory properly. So they need to be converted to new memory allocator functions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

@tlauda

tlauda commented May 30, 2019

Copy link
Copy Markdown
Contributor

@RanderWang Is there any ETA for your changes?

@RanderWang

Copy link
Copy Markdown
Collaborator Author

@RanderWang Is there any ETA for your changes?

@tlauda This PR is for sof 1.4. Now, as you know, we are busy at production release for HDA.
I will work on it after sof 1.3 released. If you have any advice, please share it.
Thanks!

Comment thread src/lib/alloc.c Outdated
uint32_t flags;
void *ptr = NULL;

if (bytes >= HEAP_BUFFER_BLOCK_SIZE)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like RZONE_BUFFER isn't used anymore.
Shouldn't it be used to take priority in allocation?
Some buffers explicitly want to be allocated directly on buffer heap and not on other heaps and some want to be allocated on system heaps. I don't see current code working with other cores running, where every core has its own system and system runtime heaps.
Also I think the current code will panic if you try to allocate buffer with bytes < HEAP_BUFFER_BLOCK_SIZE and zone RZONE_BUFFER.

Comment thread src/lib/alloc.c
break;
}

spin_unlock_irq(&memmap.lock, flags);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you are unlocking before another try to alloc.
It can possibly create race condition.

TEST_BULK, "rballoc_dma"),
TEST_CASE(256, RZONE_BUFFER, SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, 2,
TEST_BULK, "rballoc_dma"),
TEST_CASE(2048, RZONE_BUFFER, SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA, 100,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

#define HEAP_BUFFER_BLOCK_SIZE 0x180
#define HEAP_BUFFER_COUNT (HEAP_BUFFER_SIZE / HEAP_BUFFER_BLOCK_SIZE)

#define PLATFORM_BUFFER_BLOCK_SIZE (HEAP_BUFFER_BLOCK_SIZE - 64)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tlauda , please ignore this for I may rework the PR since The memory structure is significant different with the one on which I made this PR based

@lgirdwood

Copy link
Copy Markdown
Member

@RanderWang can you revisit when your done with IPC.

@RanderWang

Copy link
Copy Markdown
Collaborator Author

@RanderWang can you revisit when your done with IPC.

yes, I think I have to rework it for commit #1483 (comment). The memory structure is significant different with the one on which I made this PR based.
Maybe this PR is not needed.

I will talk with @mengdonglin about the schedule.

@lgirdwood

Copy link
Copy Markdown
Member

@RanderWang still needed as it makes the map more granular and simplifies usage.

@RanderWang

RanderWang commented Jul 9, 2019 •

Copy link
Copy Markdown
Collaborator Author

The PR: #1567 is linked to my PR.
since it removes the hp buffer heap, I need to rework my PR.

@lgirdwood

Copy link
Copy Markdown
Member

@RanderWang yep, please make sure it gets good QA coverage too.

@RanderWang

Copy link
Copy Markdown
Collaborator Author

@RanderWang yep, please make sure it gets good QA coverage too.

yes, I get it.

@lgirdwood

Copy link
Copy Markdown
Member

@mengdonglin this needs QA as its for v1.4

@lgirdwood lgirdwood modified the milestones: v1.4, v1.5 Aug 30, 2019
@tlauda

tlauda commented Oct 4, 2019

Copy link
Copy Markdown
Contributor

@RanderWang Ping.

@RanderWang

Copy link
Copy Markdown
Collaborator Author

@RanderWang Ping.

hi @mengdonglin, I will talk with you about this task.

@mengdonglin

Copy link
Copy Markdown
Collaborator

@lrgirdwo @tlauda Rander is working on SoundWire atm, do you see if someone else can take over and improve this PR? Thanks!

@RanderWang

Copy link
Copy Markdown
Collaborator Author

There are many changes in memory management since my first commit for this PR, so it will take great effort to redesign and validate the PR. Now I am occupied by soundwire project which is a high priority task and this is a low priority task, so I just close it and reopen it when I have time to implement it.

@RanderWang RanderWang closed this Oct 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

allocator: unify alloc API.

7 participants