Treat tabs as having eight spaces instead of four
For whatever bad reason, we chose to treat tabs as four spaces instead
of eight. e.g. in vim, tabstop=4.
That's a huge pain - both when dealing with other tools and when
switching between projects. I don't particularly like having
per-project vim settings and whatnot. Plus, that's a bit harder for
other people who look at our code and have their vim/emacs set to 8
space tabs.
I had regretted that for a long time, but I didn't want to make the
change for two reasons:
1) With other people working on the project, changes of this sort can
lead to merge conflicts. Since I'm the only one working on it, for the
most part, this isn't a concern.
2) The bigger reason is that major reformatting changes break git blame.
However, there are tools that can ignore commits when running git blame.
Chromium has git hyper-blame. I thought that feature ought to be baked
into git, so I have a patchset out for git to do so. Either way, I'll
either have my own patched git or the feature will get merged. In a
future commit, I'll have instructions for how to use that feature.
A lot of our files didn't need too much attention, due to our old
"spaces for formatting" policy. I didn't change those to use tabs
instead of spaces for the formatting either. I expect newer code will
just do whatever people's editors do. I didn't want to change more
lines than were needed, and the code looks the same either way.
The biggest offenders were indented comments. Structs with
column-aligned members needed some work too. I did most of that stuff
manually, since the tools do a mediocre job.
Since I was making changes, I also fixed up the switch-case indenting:
don't do an extra level of indentation for the case keywords. Doing
this now actually helped with the 8-space tab change, since switch
statements got a few spaces to work with.
A few of the kernel's C files were so badly messed up that I just used
clang-format on them. Same for Plan 9 files that had been
clang-formatted before and hadn't been heavily modified by us.
Clang-format caused a few problems with its "alphabetized headers"
policy. That was fun.
Higher-quality (subjectively) code didn't need as much work as older,
poorer code. Specifically, code with way too many levels of indentation
looks even worse than before - that's actually a benefit of 8-space
tabs: it tells you when your code is bad. A lot of that older code
needs a more serious refactoring, which this commit does not do.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Add tracing infrastructure for allocs and frees
When tracking down memory leaks, it is helpful to know if we have
allocated anything that was not freed.
Kmem tracing tracks all allocations (and their backtraces) and drops
those traces when the object is freed. This tracing happens *above* the
magazine layer, so you're seeing the actual allocs/frees. You don't
need to worry about objects hanging out in the depots. Although
stranding resources in depots is a memory management concern, it's not a
memory leak from the user of the allocator.
You can target specific caches (slab allocators) for a more fine-grained
trace - and one that may avoid false positives.
In general, you watch #men/kmemstat or slab_stats to find what is
growing that you don't expect. Then you trace it, run a test that
shouldn't increase the memory load, stop the trace, and dump the info.
You can expect a trace to not increase the load if all new processes are
destroyed and all files are either already in the page cache or are
flushed. For the most part, a single go test does this. You might get
a few kstack allocations, since kernel stacks aren't bound to particular
processes.
Note that we locklessly peek at kmc->flags. That global memory access
happens on every alloc and free, including the per-core allocations,
even when tracing is off. I'd prefer it to be as lightweight as
possible so we're less inclined to build with tracing turned off.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Warn when creating multiple caches with the same name2018-10-09T20:12:16ZBarret Rhodenbrho@cs.berkeley.eduBarret Rhodenbrho@cs.berkeley.edu2018-10-09T20:12:16Zhttp://akaros.cs.berkeley.edu/gitweb/?p=akaros.git;a=commitdiff;h=dbeec102964d68ba78c3d2d8364fa0ee9616ab03

slab: Warn when creating multiple caches with the same name
Tracing infrastructure will look up caches by name. If there is a
collision, we will only be able to trace the first one.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Catch attempted NULL frees
If someone is using the slab interface, then they need to know if they have
an object or not. This ain't like kfree().
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Properly account for allocs from slabs
Previously, we only counted the magazine allocations. However, all of the
magazines are built from direct slab allocations, which we weren't
counting.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Update the ctor/dtor interface
The priv (private) field is to support parameterized callbacks. For
instance, you might have separate kmem_caches for different parts of a
driver.
The old 'size' field was useless, since the caller should know the size of
the object (if that's even useful).
ctor can fail, and it will respect the mem flags. I have a couple ctors in
mind that could block, so they'll need to check MEM_WAIT/MEM_ATOMIC.
I moved the dtor out of free_to_slab since the ctor needs to call free
if it failed. I also considered adding a batch dtor interface so we can
free a chunk of objects at once, which could amortize the overhead of
freeing. For example, if there was an expensive operation that had to
be done after freeing any object (such as a TLB shootdown), then a batch
dtor would make sense. It turns out that I don't need this for now, so
I opted to keep the vmem paper's API.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

Remove old memory tests
They are unused and just print a bunch of stuff that no one looks at.
Also, I want to remove the printing functions in lieu of better debugging
diagnostics.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

Tracks arenas and slabs on tailqs
Both lists are protected by the arenas_and_slabs qlock. The all_arenas
list will be useful for #mem. The all_kmem_caches might not be useful,
since all caches always have a source arena. It's fine for diagnostics
for now.
The important thing is that the existence and importing links are all
managed by the same lock, so things like reclaim and #mem device ops can
happen without worrying about the read-mostly structure changing.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

arena: Connecting importers with sources
This allows us to see all arenas and slabs that import resources from
one another. Eventually we'll have a reclaim ktask for base_arena that
can trigger the various reclaim functions.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Add the magazine and depot layers
This is the per-cpu caching layer, which should increase scalability at
the cost of RAM. The per-core 2x magazines aren't free, and the objects
in those magazines are harder to reclaim.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Remove obj_size from struct kmem_slab
We actually can just look at the cache itself, which tracks the object
size already. That object size technically was the unaligned object
size, but that is mostly useless. If we want the requested, but not
actual, object size for diagnostics, we can add tracking for it.
Note that the size is passed to the ctor/dtor. That'll go away soon
too; I don't recall if it was something we added, or if it was in the
original slab paper, but it's mostly useless.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Stop appending a uintptr_t to small objects2016-11-07T00:20:13ZBarret Rhodenbrho@cs.berkeley.eduBarret Rhodenbrho@cs.berkeley.edu2016-11-07T00:20:13Zhttp://akaros.cs.berkeley.edu/gitweb/?p=akaros.git;a=commitdiff;h=9871244718039009d86c98cff000ed54e83a9237

slab: Stop appending a uintptr_t to small objects
Previously, when objects were in the slab layer (i.e., on a list in the
slab), they were constructed. Because of that, we needed to append a
uinptr_t to small objects to form a linked list so as to not use the
constructed object.
Now that constructing happens above the slab layer, we can use the
memory of the object itself for the linked list. Other than being
simpler, this saves some space and avoids fragmentation. (consider a
256 byte item - we were adding 8 bytes, which would make it not pack
neatly into a page).
Note that small objects are all 'pro-touch', so we're allowed to use the
memory of the resource we're allocating. This has always been true.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Move ctors/dtors to the slab layer
In the upcoming magazine code, objects in the slabs are unconstructed.
Right now, they'll be constructed on demand, but shortly they will be
sitting in the depot and in magazines.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

arena: Use qcaches (slabs) in the arena2016-11-03T14:46:18ZBarret Rhodenbrho@cs.berkeley.eduBarret Rhodenbrho@cs.berkeley.edu2016-11-03T14:46:18Zhttp://akaros.cs.berkeley.edu/gitweb/?p=akaros.git;a=commitdiff;h=8090054d8d5559e9d497fc54decdc1e8bf150ce6

arena: Use qcaches (slabs) in the arena
Until we get reclaim working, once memory gets added to an arena's
qcache, it'll never be returned to the arena. I'm not overly worried
about fragmentation, since we know the size of memory in the qcache is a
regularly-desired size. (e.g. PGSIZE).
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Bootstrap before setting up kpages_arena
Kpages will use kmem_cache, so we should at least run the init function
first. While we're at it, we can statically initialize the lock and list.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Move the name into the kmem_cache2016-11-02T20:44:26ZBarret Rhodenbrho@cs.berkeley.eduBarret Rhodenbrho@cs.berkeley.edu2016-11-02T20:44:26Zhttp://akaros.cs.berkeley.edu/gitweb/?p=akaros.git;a=commitdiff;h=235177117dcff253d5b66e97eb424bcd5517d00e

slab: Move the name into the kmem_cache
Instead of pointing at an arbitrary const string. The arena qcaches will
want dynamic strings, and they can't kmalloc them.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Import resources from a source arena
Previously, the implication was that all slabs pull from the general memory
allocator. Now, they will pull from their source arenas.
Careful - for small object, pro-touch caches, the slab layer assumes that
the arena is a page-aligned, memory allocator. I considered outlawing
small objects for caches with explicit sources, but we might have explicit
memory arenas in the future (e.g. one per NUMA domains).
Most slab caches will just use NULL for their source, which means a kpages
arena for generic kernel memory.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Support 'no-touch' caches
Slab allocators that are 'no-touch' will not use their source arenas for
bookkeeping. This means that we always use a bufctl to point to objects,
instead of appending a pointer to an object and making a small linked list.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>

slab: Use a hashtable when looking up bufctls2016-10-30T23:59:53ZBarret Rhodenbrho@cs.berkeley.eduBarret Rhodenbrho@cs.berkeley.edu2016-10-30T23:59:53Zhttp://akaros.cs.berkeley.edu/gitweb/?p=akaros.git;a=commitdiff;h=df9eb617c8ff352ba365e177aeb8cda85bd746d5

slab: Use a hashtable when looking up bufctls
It only took 7 years or so to take care of that TODO. Note that this is
probably slower than the old approach, which was instant. Similar to
the arena, we use hash_helper and roll our own hash table, especially
due to allocation issues when we grow the table.
Aside from being necessary for NO_TOUCH slabs, this will save a lot of
memory when it comes to fragmentation when we use slabs for arenas.
Consider kpages_arena, which will have qcaches of pages. That will be
pulling from slabs of 1 - 8 pages. The one-page slab allocator will
need to have obj_size = PGSIZE and align = PGSIZE. If we don't use the
hash and instead have the uintptr_t blob per object, we'd need two pages
per one-page-object, essentially wasting half of our memory.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>