So, our next talk is by an MN person, usually the people that make our lives difficult.
I'm joking.
But he's going to talk about new updates in a slump world.
Yes, so I live on my name is Flostimel.
I work at Susanne Kernel Court team for, I think, close to 12 years now.
And at some point, became a maintainer of the slump allocator.
And also later, commentator of the page allocator.
And one of the first thing I did after starting maintaining slump is you might remember
there were three of those initially to sell like them at the conflict time.
And I removed two of them and so now there's only a slump with the U.S.L.U.B.
So what I was looking at, what to do next, I had an idea that, because I was seeing some
subsistence developing own caches on top of Slap and not allocating directly for various
reasons I want it to look into this.
Some of those like the IO layer do it for performance reasons, because they think
they own arrays are faster than Slap, VPF had another reason that he wanted to allocate
objects in context that isn't Slap, Slap is in supported by Slap, such as an MI handler,
MIPO-3 is a new thing in the MMI for VMA management and the problem with it can start
some operation and to rewrite the three and now with the two allocator objects and it cannot
fail during that phase and also cannot free memory so what it did is pre-allocate for the
worst case and then free the unused object bags back which is not very efficient.
So I wanted to do something with the Slap allocator to support these U.S. cases so that people
don't have to write, work around, surround it and this is also something that wouldn't
be possible if we had still three allocators because these improvements would have to be
done in all of them so settling on just a single allocator helped in this case and hopefully
by doing that we would also improve the performance of the Slap allocator by combining
the best of designs of the remaining allocator and the Slap with A that was deleted.
So I need to spend some time explaining how they work.
So Slap allocator you have it's allocating objects that are smaller than a page so it
starts with a page and it slides to set up to a small objects of the same size and some
of them would be allocated or free at any given moment and there's some management structure
that remembers which of those objects are free and how many of them are there and how
many are used.
There's already a difference between how the SLAB worked and the SLUB works.
SLUB has this embedded free list in the objects that are currently free which makes it
possible to do some atomic operations like allocating or freeing one or multiple objects
at once in a single atomic operation.
But you need more than one SLUB because there are many objects so they are usually linked
on some per-numanoid structure.
There might be multiple lists because we distinguish slops that are free, that are partially
full or fully full and there will be some spin lock to protect this structure and this
list of Slap from concurrent modification and if you only have this it wouldn't really
scale well because every operation would take the spin lock and multiple CPUs would
continue it.
So, the allocator always has some kind of per-CPU cacheing layer and it is now that this
is much simpler to implement for allocating than for freeing for different reasons.
The old SLUB had basically array of objects that were allocated from the SLUB but were put
into this array and not yet given out to the consumers and when this array got full it
was flushed when it was empty it would be refilled from the Slap from the slabs and this
immortalizes the operation with the spin lock you allocator free multiple objects at once
and it proves performance.
The new Slap with you has the different kind of scheme where each CPU has completely
private Slop that it can operate on.
It turns out that it wasn't enough to have just once so later there was at least more
of them that it could use when the main one got depleted and this allows some nice fast
parts, again do some compare extension operation that doesn't even have to be atomic
because it's on the same CPU on the local CPU only but for freeing it only works if you're
freeing object to the same Slap that's currently on the same CPU installed as the CPU
cache Slop which turns out isn't often the case because you might have allocated object
some time ago or migrated to different CPUs so the fast part was annotated as likely but
it was actually alive because it wasn't all that likely to happen because there are many
slaps and the chance that this particular Slop is on the same CPU is quite low and the
Slop part is this more expensive atomic operation it's not bad but it's not as good at
the fast part so the idea of SHIFT is to combine basically these two approaches so we would
again have fixed capacity array of objects for cache them on given CPU and also some
pernumanoat bar that can cache these shifts between different CPU and yeah I do I think
to make you well cooked for inventing these terminologies so we don't have to use the magazine
worked this military connotation and yeah so this avoids the issues of the old Slop design
by using the current Slops slow path for freeing remote objects which which turns out it
happens only in maybe 5% of the case is but we have improved the fast part and make it more likely
by just putting the object to a per CPU array and not relying on the same Slop being on the same
CPU there's also a usage of new looking primitive local trial octid that makes the
looking of these per CPU sheets less expensive than the usual local local iRQ safe so that's
again a improvement and for the maple tree use case that was one of the motivations we also have
an API where the maple tree can ask for a shift of at least given amount of object because it
can calculate this worst case estimation before starting the critical operation and in the ideal
case we just give it the shift from the CPU it will only use as many objects that it needs
to rate the critical operation those allocations cannot fail and then ideally it returns the
shift back if you just put it on the CPU and it has only few less objects than before so this
is much cheaper than pre-allocating and returning a bunch of objects we can also optimise pay
frrsu which is freeing objects with rsu grace period by creating another per CPU sheave that collects
the subjects that were subjected to k3rsu and only once it's full we use the rsu machinery to process
the whole sheave and then reuse it again without dealing with the individual objects as
was done before so that should also improve the performance so that's roughly the design of the
sheave's in slope allocator now the status in fix 18 the implementation was merged and there were
only two opt-in users that we looked at initially the VMAs and the maple tree nose because they
use the extra features and luckily the kernel didn't explode and nobody reported some crazy
regressions so that first step was okay but but it's not ideal to stop there because
the introduce a new caching layer but it's opt-in and there's still the old caching layer as a fallback
so that's more cold and I like to have less cold and it's also unclear which caches
would like qualify to start using this I guess everyone would want to if it improves performance
so of course the next step is to go all the way and enable this for all the caches and
repout the previous caching layer so that's the that's what the current series does that's now in Linux
next and since much window starts soon hopefully nothing will explode and it would go in so the
conversion isn't wasn't anything special there would just some fun with bootstrapping
do thing and preventing recursion because she's are allocated by k maloch which is
slope allocation from specific caches for each object size and we want the k malochesh is to use
chief so there's a chicken and egg problem but this is also available and it has been similar
problems have been there before and were solved one question was how to how to select the chief size
because the larger it is the the better it abortizes the operation but you potentially waste more
memory if if not nobody allocates the objects that are sitting there so initially what I try
is to size them in a way that would be similar to how to how the cpu and per cpu partial
caches or slabs were used so so roughly the same amount of objects would be cached as a result
and hopefully the automatic kernel bots would then not report any unexpected changes in
performance just because we are caching different amount of things so it would look like the
new code maybe as a problem but it's just a tuning issue so I try to be as close to the original
as possible but it's of course possible to tune it later once the thing is in and then the fun
part was removing lots of code of the old implementation and the per cpu caches and partial slabs and
not all of that was removed because the freeing slow part it's still there and it's very useful
I also had a lot of fun with debugging the memory that came up in benchmarking
and even wasn't found by Chris Mason's AI power review which is otherwise quite useful but
it didn't find it but after he fixed the prompt by after I reported it he says now it should
be found with i probability of course the question is what about performance and I don't have any
great answer in terms of graphs because because some of the bugs and leaks were fixed quite
last minute and I couldn't get fresh numbers in time so it would be a waste of time to present
anything but but initially it was very far that yes the new fast parts are slightly faster than
the old fast part because the looking is cheaper and yeah then it's about tuning and heavy sticks
and out any particular workload happens to benefit or not from what it's doing so
overall I would say that things were slightly faster or same or in some workloads slightly slower
and there are some regulations reported by the channel to store that we were looking into and
it turns out that yeah it wasn't as bad as it initially looked because it was testing some
commits in isolation but basically the trade-offs here are that the very CPU slot and we allocate
from it all the objects are from the same page so it's better for the LB overhead but it's
worse for cash performance because some of them might be called and with the Per CPU she's
which are the arrays where you allocate in and free in a lethal order the objects you most recently
free will be the one that you will be allocated next so if it was cash-hot it's likely it would still
be cash-hot so that's better for this and yeah I think the biggest benefit should be the
freeing which should now be hitting the fast but much much more often than the original slot
and there are also other aspects why we want to implement like push this to the kernel sooner
than later because as I was saying one of the motivations was for BPS but before I envision that
she should be part of the solution for BPS so it can allocate and in my context mean why I like
to say the PF maintainer came up with a lot of knowledge that can do that without sheeps and it was
actually much at the same time as sheeps but there are a number of limitations where it cannot be used
in preempt RT and it turns out that the sheeps when we replace the old CPU cashing scheme it actually
can remove those limitations because the operations are conceptual is simpler so that's
that's why I hope that it will be much in the next version of Windows so thank you