aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2009-07-03 09:44:05 -0400
committerThomas Gleixner <tglx@linutronix.de>2009-07-24 11:45:47 -0400
commit1578a2b7d1300f4e27cea087e6cdce9b8fbbcb4a (patch)
treebffa5be9a29b71d5299f975ba6b652f70da827ba /include/linux
parent46167aec68f48cbbeff23cae9173bc4d19a7bcda (diff)
mm: quicklist: Convert to percpu locked
Use per cpu locked for quicklists as well to make the code preemptible. [ tglx: folded Ingo's "release before free page fix" ] Signed-off-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/quicklist.h27
1 files changed, 18 insertions, 9 deletions
diff --git a/include/linux/quicklist.h b/include/linux/quicklist.h
index bd466439c588..1bc3d46b9294 100644
--- a/include/linux/quicklist.h
+++ b/include/linux/quicklist.h
@@ -18,7 +18,7 @@ struct quicklist {
18 int nr_pages; 18 int nr_pages;
19}; 19};
20 20
21DECLARE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK]; 21DECLARE_PER_CPU_LOCKED(struct quicklist, quicklist)[CONFIG_NR_QUICK];
22 22
23/* 23/*
24 * The two key functions quicklist_alloc and quicklist_free are inline so 24 * The two key functions quicklist_alloc and quicklist_free are inline so
@@ -30,19 +30,27 @@ DECLARE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK];
30 * The fast patch in quicklist_alloc touched only a per cpu cacheline and 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. 31 * the first cacheline of the page itself. There is minmal overhead involved.
32 */ 32 */
33static inline void *quicklist_alloc(int nr, gfp_t flags, void (*ctor)(void *)) 33static inline void *__quicklist_alloc(struct quicklist *q)
34{ 34{
35 struct quicklist *q; 35 void **p = q->page;
36 void **p = NULL;
37 36
38 q =&get_cpu_var(quicklist)[nr];
39 p = q->page;
40 if (likely(p)) { 37 if (likely(p)) {
41 q->page = p[0]; 38 q->page = p[0];
42 p[0] = NULL; 39 p[0] = NULL;
43 q->nr_pages--; 40 q->nr_pages--;
44 } 41 }
45 put_cpu_var(quicklist); 42 return p;
43}
44
45static inline void *quicklist_alloc(int nr, gfp_t flags, void (*ctor)(void *))
46{
47 struct quicklist *q;
48 void **p;
49 int cpu;
50
51 q = &get_cpu_var_locked(quicklist, &cpu)[nr];
52 p = __quicklist_alloc(q);
53 put_cpu_var_locked(quicklist, cpu);
46 if (likely(p)) 54 if (likely(p))
47 return p; 55 return p;
48 56
@@ -56,12 +64,13 @@ static inline void __quicklist_free(int nr, void (*dtor)(void *), void *p,
56 struct page *page) 64 struct page *page)
57{ 65{
58 struct quicklist *q; 66 struct quicklist *q;
67 int cpu;
59 68
60 q = &get_cpu_var(quicklist)[nr]; 69 q = &get_cpu_var_locked(quicklist, &cpu)[nr];
61 *(void **)p = q->page; 70 *(void **)p = q->page;
62 q->page = p; 71 q->page = p;
63 q->nr_pages++; 72 q->nr_pages++;
64 put_cpu_var(quicklist); 73 put_cpu_var_locked(quicklist, cpu);
65} 74}
66 75
67static inline void quicklist_free(int nr, void (*dtor)(void *), void *pp) 76static inline void quicklist_free(int nr, void (*dtor)(void *), void *pp)