On Tue, Mar 14, 2023 at 09:05:13AM +0100, Vlastimil Babka wrote: > The immediate benefit of that is that we can allow kfree() (and kfree_rcu()) > to free objects from kmem_cache_alloc() - something that IIRC at least xfs > people wanted in the past, and SLOB was incompatible with that. > > For SLAB removal I haven't yet heard any objections (but also didn't > deprecate it yet) but if there are any users due to particular workloads > doing better with SLAB than SLUB, we can discuss why those would regress and > what can be done about that in SLUB. > > Once we have just one slab allocator in the kernel, we can take a closer > look at what the users are missing from it that forces them to create own > allocators (e.g. BPF), and could be considered to be added as a generic > implementation to SLUB. With kfree() now working on kmem_cache_alloc(), I'd like to re-propose the introduction of a generic free() function which can free any allocated object. It starts out looking a lot like kvfree(), but can be enhanced to cover other things ... here's a version I did from 2018 before giving up on it when I realised slob made it impossible: +/** + * free() - Free memory + * @ptr: Pointer to memory + * + * This function can free almost any type of memory. It can safely be + * called on: + * * NULL pointers. + * * Pointers to read-only data (will do nothing). + * * Pointers to memory allocated from kmalloc(). + * * Pointers to memory allocated from kmem_cache_alloc(). + * * Pointers to memory allocated from vmalloc(). + * * Pointers to memory allocated from alloc_percpu(). + * * Pointers to memory allocated from __get_free_pages(). + * * Pointers to memory allocated from page_frag_alloc(). + * + * It cannot free memory allocated by dma_pool_alloc() or dma_alloc_coherent(). + */ +void free(const void *ptr) +{ + struct page *page; + + if (unlikely(ZERO_OR_NULL_PTR(ptr))) + return; + if (is_kernel_rodata((unsigned long)ptr)) + return; + + page = virt_to_head_page(ptr); + if (likely(PageSlab(page))) + return kmem_cache_free(page->slab_cache, (void *)ptr); + + if (is_vmalloc_addr(ptr)) + return vfree(ptr); + if (is_kernel_percpu_address((unsigned long)ptr)) + free_percpu((void __percpu *)ptr); + if (put_page_testzero(page)) + __put_page(page); +} +EXPORT_SYMBOL(free); Looking at it now, I'd also include a test for stack memory (and do nothing if it is) There are some prep patches that I'm not including here to clear out the use of 'free' as a function name (some conflicting identifiers named 'free') and a fun one to set a SLAB_PAGE_DTOR on compound pages.