[dpdk-dev] [RFC v2 00/23] Dynamic memory allocation for DPDK
Burakov, Anatoly
anatoly.burakov at intel.com
Wed Apr 25 18:02:48 CEST 2018
On 14-Feb-18 10:07 AM, Burakov, Anatoly wrote:
> On 14-Feb-18 8:04 AM, Thomas Monjalon wrote:
>> Hi Anatoly,
>>
>> 19/12/2017 12:14, Anatoly Burakov:
>>> * Memory tagging. This is related to previous item. Right now, we
>>> can only ask
>>> malloc to allocate memory by page size, but one could potentially
>>> have
>>> different memory regions backed by pages of similar sizes (for
>>> example,
>>> locked 1G pages, to completely avoid TLB misses, alongside
>>> regular 1G pages),
>>> and it would be good to have that kind of mechanism to
>>> distinguish between
>>> different memory types available to a DPDK application. One
>>> could, for example,
>>> tag memory by "purpose" (i.e. "fast", "slow"), or in other ways.
>>
>> How do you imagine memory tagging?
>> Should it be a parameter when requesting some memory from rte_malloc
>> or rte_mempool?
>
> We can't make it a parameter for mempool without making it a parameter
> for rte_malloc, as every memory allocation in DPDK works through
> rte_malloc. So at the very least, rte_malloc will have it. And as long
> as rte_malloc has it, there's no reason why memzones and mempools
> couldn't - not much code to add.
>
>> Could it be a bit-field allowing to combine some properties?
>> Does it make sense to have "DMA" as one of the purpose?
>
> Something like a bitfield would be my preference, yes. That way we could
> classify memory in certain ways and allocate based on that. Which
> "certain ways" these are, i'm not sure. For example, in addition to
> tagging memory as "DMA-capable" (which i think is a given), one might
> tag certain memory as "non-default", as in, never allocate from this
> chunk of memory unless explicitly asked to do so - this could be useful
> for types of memory that are a precious resource.
>
> Then again, it is likely that we won't have many types of memory in
> DPDK, and any other type would be implementation-specific, so maybe just
> stringly-typing it is OK (maybe we can finally make use of "type"
> parameter in rte_malloc!).
>
>>
>> How to transparently allocate the best memory for the NIC?
>> You take care of the NUMA socket property, but there can be more
>> requirements, like getting memory from the NIC itself.
>
> I would think that we can't make it generic enough to cover all cases,
> so it's best to expose some API's and let PMD's handle this themselves.
>
>>
>> +Cc more people (6WIND, Cavium, Chelsio, Mellanox, Netronome, NXP,
>> Solarflare)
>> in order to trigger a discussion about the ideal requirements.
>>
>
Hi all,
I would like to restart this discussion, again :) I would like to hear
some feedback on my thoughts below.
I've had some more thinking about it, and while i have lots of use-cases
in mind, i suspect covering them all while keeping a sane API is
unrealistic.
So, first things first.
Main issue we have is the 1:1 correspondence of malloc heap, and socket
ID. This has led to various attempts to hijack socket id's to do
something else - i've seen this approach a few times before, most
recently in a patch by Srinath/Broadcom [1]. We need to break this
dependency somehow, and have a unique heap identifier.
Also, since memory allocators are expected to behave roughly similar to
drivers (e.g. have a driver API and provide hooks for init/alloc/free
functions, etc.), a request to allocate memory may not just go to the
heap itself (which is handled internally by rte_malloc), but also go to
its respective allocator. This is roughly similar to what is happening
currently, except that which allocator functions to call will then
depend on which driver allocated that heap.
So, we arrive at a dependency - heap => allocator. Each heap must know
to which allocator it belongs - so, we also need some kind of way to
identify not just the heap, but the allocator as well.
In the above quotes from previous mails i suggested categorizing memory
by "types", but now that i think of it, the API would've been too
complex, as we would've ideally had to cover use cases such as "allocate
memory of this type, no matter from which allocator it comes from",
"allocate memory from this particular heap", "allocate memory from this
particular allocator"... It gets complicated pretty fast.
What i propose instead, is this. In 99% of time, user wants our hugepage
allocator. So, by default, all allocations will come through that. In
the event that user needs memory from a specific heap, we need to
provide a new set of API's to request memory from a specific heap.
Do we expect situations where user might *not* want default allocator,
but also *not* know which exact heap he wants? If the answer is no
(which i'm counting on :) ), then allocating from a specific malloc
driver becomes as simple as something like this:
mem = rte_malloc_from_heap("my_very_special_heap");
(stringly-typed heap ID is just an example)
So, old API's remain intact, and are always passed through to a default
allocator, while new API's will grant access to other allocators.
Heap ID alone, however, may not provide enough flexibility. For example,
if a malloc driver allocates a specific kind of memory that is
NUMA-aware, it would perhaps be awkward to call different heap ID's when
the memory being allocated is arguably the same, just subdivided into
several blocks. Moreover, figuring out situations like this would likely
require some cooperation from the allocator itself (possibly some
allocator-specific API's), but should we add malloc heap arguments,
those would have to be generic. I'm not sure if we want to go that far,
though.
Does that sound reasonable?
Another tangentially related issue raised by Olivier [1] is of
allocating memory in blocks, rather than using rte_malloc. Current
implementation has rte_malloc storing its metadata right in the memory -
this leads to unnecessary memory fragmentation in certain cases, such as
allocating memory page-by-page, and in general polluting memory we might
not want to pollute with malloc metadata.
To fix this, memory allocator would have to store malloc data
externally, which comes with a few caveats (reverse mapping of pointers
to malloc elements, storing, looking up and accounting for said
elements, etc.). It's not currently planned to work on it, but it's
certainly something to think about :)
[1] http://dpdk.org/dev/patchwork/patch/36596/
[2] http://dpdk.org/ml/archives/dev/2018-March/093212.html
--
Thanks,
Anatoly
More information about the dev
mailing list