mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 17:30:02 +00:00
![Nitin Gupta](/assets/img/avatar_default.png)
* Features: - Low metadata overhead (just 4 bytes per object) - O(1) Alloc/Free - except when we have to call system page allocator to get additional memory. - Very low fragmentation: In all tests, xvmalloc memory usage is within 12% of "Ideal". - Pool based allocator: Each pool can grow and shrink. - It maps pages only when required. So, it does not hog vmalloc area which is very small on 32-bit systems. SLUB allocator could not be used due to fragmentation issues: http://code.google.com/p/compcache/wiki/AllocatorsComparison Data here shows kmalloc using ~43% more memory than TLSF and xvMalloc is showed ~2% more space efficiency than TLSF (due to smaller metadata). Creating various kmem_caches can reduce space efficiency gap but still problem of being limited to low memory exists. Also, it depends on allocating higher order pages to reduce fragmentation - this is not acceptable for ramzswap as it is used under memory crunch (its a swap device!). SLOB allocator could not be used do to reasons mentioned here: http://lkml.org/lkml/2009/3/18/210 * Implementation: It uses two-level bitmap search to find free list containing block of correct size. This idea is taken from TLSF (Two-Level Segregate Fit) allocator and is well explained in its paper (see [Links] below). * Limitations: - Poor scalability: No per-cpu data structures (work in progress). [Links] 1. Details and Performance data: http://code.google.com/p/compcache/wiki/xvMalloc http://code.google.com/p/compcache/wiki/xvMallocPerformance 2. TLSF memory allocator: home: http://rtportal.upv.es/rtmalloc/ paper: http://rtportal.upv.es/rtmalloc/files/MRBC_2008.pdf Signed-off-by: Nitin Gupta <ngupta@vflare.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
86 lines
1.7 KiB
C
86 lines
1.7 KiB
C
/*
|
|
* xvmalloc memory allocator
|
|
*
|
|
* Copyright (C) 2008, 2009 Nitin Gupta
|
|
*
|
|
* This code is released using a dual license strategy: BSD/GPL
|
|
* You can choose the licence that better fits your requirements.
|
|
*
|
|
* Released under the terms of 3-clause BSD License
|
|
* Released under the terms of GNU General Public License Version 2.0
|
|
*/
|
|
|
|
#ifndef _XV_MALLOC_INT_H_
|
|
#define _XV_MALLOC_INT_H_
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/types.h>
|
|
|
|
/* User configurable params */
|
|
|
|
/* Must be power of two */
|
|
#define XV_ALIGN_SHIFT 2
|
|
#define XV_ALIGN (1 << XV_ALIGN_SHIFT)
|
|
#define XV_ALIGN_MASK (XV_ALIGN - 1)
|
|
|
|
/* This must be greater than sizeof(link_free) */
|
|
#define XV_MIN_ALLOC_SIZE 32
|
|
#define XV_MAX_ALLOC_SIZE (PAGE_SIZE - XV_ALIGN)
|
|
|
|
/* Free lists are separated by FL_DELTA bytes */
|
|
#define FL_DELTA_SHIFT 3
|
|
#define FL_DELTA (1 << FL_DELTA_SHIFT)
|
|
#define FL_DELTA_MASK (FL_DELTA - 1)
|
|
#define NUM_FREE_LISTS ((XV_MAX_ALLOC_SIZE - XV_MIN_ALLOC_SIZE) \
|
|
/ FL_DELTA + 1)
|
|
|
|
#define MAX_FLI DIV_ROUND_UP(NUM_FREE_LISTS, BITS_PER_LONG)
|
|
|
|
/* End of user params */
|
|
|
|
enum blockflags {
|
|
BLOCK_FREE,
|
|
PREV_FREE,
|
|
__NR_BLOCKFLAGS,
|
|
};
|
|
|
|
#define FLAGS_MASK XV_ALIGN_MASK
|
|
#define PREV_MASK (~FLAGS_MASK)
|
|
|
|
struct freelist_entry {
|
|
struct page *page;
|
|
u16 offset;
|
|
u16 pad;
|
|
};
|
|
|
|
struct link_free {
|
|
struct page *prev_page;
|
|
struct page *next_page;
|
|
u16 prev_offset;
|
|
u16 next_offset;
|
|
};
|
|
|
|
struct block_header {
|
|
union {
|
|
/* This common header must be ALIGN bytes */
|
|
u8 common[XV_ALIGN];
|
|
struct {
|
|
u16 size;
|
|
u16 prev;
|
|
};
|
|
};
|
|
struct link_free link;
|
|
};
|
|
|
|
struct xv_pool {
|
|
ulong flbitmap;
|
|
ulong slbitmap[MAX_FLI];
|
|
spinlock_t lock;
|
|
|
|
struct freelist_entry freelist[NUM_FREE_LISTS];
|
|
|
|
/* stats */
|
|
u64 total_pages;
|
|
};
|
|
|
|
#endif
|