The Advantages of using a Slab Allocator

When people take their first C programming courses, they are taught about the standard allocator named ‘malloc()‘, while when learning C++, we were first taught about its standard allocator, named ‘new‘.

These allocators work on the assumption that a program is running in user space, and may not always be efficient at allocating smaller chunks of memory. They assume that a standard method of managing the heap is in-place, where the heap of any one process is a part of that process’s memory-image, and partially managed by the kernel.

Not only that, but when we tell either of these standard operators to allocate a chunk of memory, the allocator recognizes the size of that chunk, prepends to the chunk of memory a binary representation of its size, and before returning a pointer to the allocated memory, subtracts the size of the binary representation, of the size originally requested by the programmer. Thus, the pointer returned by either of these allocators points directly to the memory which the programmer can use, even though the allocated chunk is larger, and preceded by a binary representation of its own size. That way, when the command is given to deallocate, all the deallocation-function needs to receive in principle, is a pointer to the allocated chunk, and the deallocation-function can then find the header that was inserted from there, to derive how much memory to delete.

I suppose that one conclusion to draw from this is, that even though it looks like a good exercise to teach programming students, the exercise of always allocating a 32-bit or a 64-bit object – i.e., a 4-byte or an 8-byte object – such as an integer, to obtain an 8-byte pointer to that integer, is actually not a good one, because in addition to the requested 8 bytes, an additional header is always being allocated, which may add 4 bytes if the maximum allocated size is a 32-bit number, or add 8 bytes if the maximum allocated size (of one chunk) is a 64-bit number.

Additionally, these allocators assume the support of the kernel, to a user-space process, the latter of which has a heap. On 64-bit systems that are ‘vmalloc‘-based, this requires the user-space application try to access virtual address ‘0x0000 0000 0000 0000‘, which intentionally results in a page-fault, and stops the process. The kernel then needs to examine why the page-fault occurred, and since this was a legitimate reason, needs to set up the virtual page-frame, of an address returned to the (restarted) user-space process, via the usual methods for returning values.

And so means also needed to exist, by which a kernel can manage memory more-efficiently, even under the assumption that the kernel does not have the sort of heap, that a user-space process does. And one main mechanism for doing so, is to use a slab allocator. It will allocate large numbers of small chunks, without requiring as much overhead to do so, as the standard user-space allocators did. In kernel-space, these slabs are the main replacement for a heap.

(Updated 06/20/2017 … )

Continue reading The Advantages of using a Slab Allocator

Why a Hard-Boot is often Overkill.

In order to understand this posting, the reader first needs to understand something, about how the (volatile) memory in a computer is organized. Through the use of virtual addresses, it gets organized into user-space and kernel-space. User-space includes programs that run with elevated privileges, but also the GUI-programs that display widgets and the like on the screen. Kernel-space is reserved for the kernel of the O/S, as well as for kernel-modules, that act as device drivers in practice.

But in addition to that, modern architectures also have I/O chips – which the kernel modules would be responsible for – that run “firmware”. These more-complex I/O chips will often perform complex tasks, such as the encryption built-in to Bluetooth, without requiring that these tasks run on the CPU, or in RAM. In order to do that, I/O chips capable of doing so need a smaller program of instructions, that actually run on the I/O chip. This program is typically no longer than 1-2 KB.

(Edit 06/09/2017 :

I suppose the fact should also be acknowledged, that in order for the firmware actually to do anything, the I/O chip should also have a somewhat larger region of memory – call it a Buffer – which stores data and not code. In the case of an intelligent Bluetooth chip, that buffer would logically store whatever encryption keys are currently being applied to data, which is being streamed to and from the chip… )

So in practice, a situation which the user can run in to, is that by unpairing all his (external) Bluetooth devices, and then turning Bluetooth Off from the settings GUI, and next turning BT back On, he can Fail to Reset the Bluetooth system to its original state. The user only gets to see what the GUI is showing him – which is being controlled by programs running in user-space.

What the user may not realize, is that the way kernel-space is often organized, turning Bluetooth Off in user-space, will fail to unload the kernel-module itself, responsible for operating the Bluetooth Chip, that has firmware running on it, for the sake of argument.

The actual kernel-modules first load when the computer boots up, and the first thing they do, if they are of the sort that use firmware, is to load that firmware onto the I/O chip – and it’s often patches to the firmware that get loaded, because the default firmware is burned-in to the I/O chip.

Continue reading Why a Hard-Boot is often Overkill.