Hi Mattias,

> This RFC introduces fastmem, a general-purpose small-object allocator
> for DPDK. It is intended to replace per-type mempools with a single
> allocator that handles arbitrary sizes, grows on demand, and matches
> mempool-level performance on the hot path.

As stated before, I summitted RFC for the one we use internally:
https://patchwork.dpdk.org/project/dpdk/patch/[email protected]/
Many things and ideas are similar, some are not.
Below I tried to summarize the main differences (as I see them).
I do understand that our use-cases and requirements are different,
but might be we can have a blend that will fit all of us.
Another two things that are probably necessary to move forward:
- some unified set of stress/performance test-caces that we can run
  against all three: mempool/fastmem/memtank.
- some sort of guinea-pig: DPDK sub-component where this new lib     
  can be applied. We can try straight with the mbuf, but that's probably
  quite ambitious choice for the first integration. Again, this is just one
  of the possible usage scenarios.   

Let me know what are your thoughts here.
Thanks
Konstantin 

> Motivation
> ----------
> 
> DPDK applications commonly maintain many mempools — one per object
> type (connections, sessions, timers, work items). Each must be sized
> up front, wastes memory when over-provisioned, and cannot serve
> objects of a different size. Fastmem eliminates this by accepting
> arbitrary sizes at runtime, backed by a slab allocator that
> repurposes memory across size classes as demand shifts.

I agree about first one - it is a big problem that you have to over-provision
everything with the mempool these days.  
About forcing user to explicitly create multiple pools - for me it is not such 
big problem,  
after all in most cases user knows the size of the objects he need to 
alloc/free upfront.
AFAIK - majority of SLAB-based allocators these days support both flavors:
user can create/maintain his own SLAB for some specific object types, or use 
generic
alloc/free which is backed by bunch of SLABs underneath, each serving specific 
size.
Might be we can do the same and support both too. 
 
> 
> Design
> ------
> 
> Three-layer architecture:
> 
> 1. Backing memory: 128 MiB IOVA-contiguous memzones from EAL,
>    reserved lazily (or pre-reserved for deterministic latency).
> 2. Slabs: 2 MiB, 2 MiB-aligned regions carved from memzones.

In many cases, user don't need DMA-capabl;e memory for such objects,
so simple rte_malloc or even libc malloc might be enough.
I understand the intention - it is probably the fastest way to do things,
but I think it is way too constrained.
Might be the best approach is to do what memtank does -
allow user to define his own allox/free/init callbacks, then fastmem
approach will become just one of possible cases.      

>    The alignment enables O(1) slab lookup from any object pointer
>    via bitmask — no radix tree or index structure. Slabs move
>    freely between 18 power-of-2 size classes (8 B to 1 MiB).

That is cool idea and thought about doing the same: limit possible size
for SLAB to power-of-two values. 
But then I realized that we still need to store inside the object some
extra metadata for stats and sanity-checking. So extra 8B for a SLAB
pointer doesn't make much difference.
But again - I think we can support both and make it configurable at creation 
time.
 
> 3. Per-lcore caches: bounded LIFO stacks (no locks on the hot
>    path). Cache misses trigger bulk transfers to/from the shared
>    bin under a spinlock.

memtank lacks of per-lcore caches right now, mostly due to lack of time
to implement it. It is definitely a good feature - way to go.  
 
> Key properties:
> 
> - Zero per-object metadata in the production build.
> - NUMA-aware, with per-socket bins and free-slab pools.
> - DMA-usable memory with O(1) virt-to-IOVA translation.
> - Bulk alloc/free with all-or-nothing semantics.

Personally, I don't find it very convenient.
For most cases we care about - we do use best-effort semantics.
Again, probably we can support both, same as rte_ring API.
 
> - Backing memory never returned during lifetime (slabs recycled).

For our case it is important to have ability return memory back to the system.
memtank lib supports it (though of course some fragmentation is possible).
Again it is much easier with separate pools.
What I really like with fastmem - that one SLAB can re-use memory from different
one, that seems usefull and might mitigate memory footprint growth till some 
extent.
Again, I suppose both flavors caon coexist:
individual pools can grow/shring, while fasmem (bunch of predefined pools) will 
not. 
 
> - Non-EAL threads supported (bypass cache, take bin lock).
> - Secondary process support (lazy attach, no per-lcore caches).
> 

Reply via email to