Re: [PATCH] rust: slab: add basic slab module

Danilo Krummrich
2025-09-26T16:58:11Z

On Fri Sep 26, 2025 at 6:32 PM CEST, Vlastimil Babka wrote:
> On 9/26/25 17:55, Danilo Krummrich wrote:
>> On Fri Sep 26, 2025 at 5:33 PM CEST, Danilo Krummrich wrote:
>>> The only thing we need on the Rust side is that existing allocations remain
>>> valid even if the cache is destroyed. Or the other way around the cache is
>>> silently kept alive internally.
>>
>> Or to express it in C code:
>>
>> struct kmem_cache *cache = kmem_cache_create();
>> struct Foo *foo = kmem_cache_alloc();
>>
>> // After this call cache will never be accessed; leaves a zombie cache,
>> // since foo is still alive.
>> kmem_cache_destroy(cache);
>
> This will cause a WARN.
>
>> // This must still be valid.
>> foo->bar = 42;
>
> Yes this will be safe.

That's great!

>> // Frees foo and causes the "zombie" cache to actually be destroyed.
>> kmem_cache_free(foo);
>
> The free will be fine. But not cause the cache destruction, as that would
> require checks on each free. But should be fine wrt safety if we only leak
> some memory due to a wrong usage, no?

Yes, technically that's safe, but we wouldn't prevent the leak, which still
is not desirable (and not our ambition for a Rust API).

From a C standpoint, both the warning and the cache leak could be solved by
making kmem_cache_destroy() fallible as you mentioned previously.

On the Rust side the cache would be represented with a struct KmemCache<T>
(where T is the type that should be allocated by the cache).

kmem_cache_destroy() would be called from KmemCache<T>::drop(), which is not
fallible. But even if it were, we can't enforce that users keep the KmemCache
instance alive as long as there are allocations.

So, either we always keep the KmemCache<T> alive for the whole module lifetime
(which depending on whether its built-in or not could be considered a memory
leak as well). Or we ensure that the last kmem_cache_free() also frees the cache
if kmem_cache_destroy() was called previously.

OOC, does the cache pointer remain valid if kmem_cache_destroy() is called while
allocations still exist? I.e. is this, except for the WARN(), valid code?

kmem_cache_destroy(cache);
kmem_cache_free(foo);
kmem_cache_destroy(cache);

At a quick glance it appears to me that things would go south in
kmem_cache_release(). Anyways, I don't think it would help, if it would be the
case.