1#ifndef LINUX_QUICKLIST_H 2#define LINUX_QUICKLIST_H 3/* 4 * Fast allocations and disposal of pages. Pages must be in the condition 5 * as needed after allocation when they are freed. Per cpu lists of pages 6 * are kept that only contain node local pages. 7 * 8 * (C) 2007, SGI. Christoph Lameter <clameter@sgi.com> 9 */ 10#include <linux/kernel.h> 11#include <linux/gfp.h> 12#include <linux/percpu.h> 13 14#ifdef CONFIG_QUICKLIST 15 16struct quicklist { 17 void *page; 18 int nr_pages; 19}; 20 21DECLARE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK]; 22 23/* 24 * The two key functions quicklist_alloc and quicklist_free are inline so 25 * that they may be custom compiled for the platform. 26 * Specifying a NULL ctor can remove constructor support. Specifying 27 * a constant quicklist allows the determination of the exact address 28 * in the per cpu area. 29 * 30 * The fast patch in quicklist_alloc touched only a per cpu cacheline and 31 * the first cacheline of the page itself. There is minmal overhead involved. 32 */ 33static inline void *quicklist_alloc(int nr, gfp_t flags, void (*ctor)(void *)) 34{ 35 struct quicklist *q; 36 void **p = NULL; 37 38 q =&get_cpu_var(quicklist)[nr]; 39 p = q->page; 40 if (likely(p)) { 41 q->page = p[0]; 42 p[0] = NULL; 43 q->nr_pages--; 44 } 45 put_cpu_var(quicklist); 46 if (likely(p)) 47 return p; 48 49 p = (void *)__get_free_page(flags | __GFP_ZERO); 50 if (ctor && p) 51 ctor(p); 52 return p; 53} 54 55static inline void __quicklist_free(int nr, void (*dtor)(void *), void *p, 56 struct page *page) 57{ 58 struct quicklist *q; 59 60 q = &get_cpu_var(quicklist)[nr]; 61 *(void **)p = q->page; 62 q->page = p; 63 q->nr_pages++; 64 put_cpu_var(quicklist); 65} 66 67static inline void quicklist_free(int nr, void (*dtor)(void *), void *pp) 68{ 69 __quicklist_free(nr, dtor, pp, virt_to_page(pp)); 70} 71 72static inline void quicklist_free_page(int nr, void (*dtor)(void *), 73 struct page *page) 74{ 75 __quicklist_free(nr, dtor, page_address(page), page); 76} 77 78void quicklist_trim(int nr, void (*dtor)(void *), 79 unsigned long min_pages, unsigned long max_free); 80 81unsigned long quicklist_total_size(void); 82 83#else 84 85static inline unsigned long quicklist_total_size(void) 86{ 87 return 0; 88} 89 90#endif 91 92#endif /* LINUX_QUICKLIST_H */ 93 94