aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slub.c
diff options
context:
space:
mode:
authorPekka Enberg <penberg@kernel.org>2012-06-04 03:14:58 -0400
committerPekka Enberg <penberg@kernel.org>2012-06-04 03:14:58 -0400
commit23910c50cced8f35d53e4f8ea0cc09ad58d286af (patch)
tree4e5c9ef6a09d234119a49d2623a0d042fe3af125 /mm/slub.c
parentf8f5701bdaf9134b1f90e5044a82c66324d2073f (diff)
parent57d437d2aa680f42d75cef45205834d5f605550a (diff)
Merge branch 'slub/cleanups' into slab/next
* Fix a merge conflict in mm/slub.c::acquire_slab() due to commit 02d7633 ("slub: fix a memory leak in get_partial_node()"). Conflicts: mm/slub.c Signed-off-by: Pekka Enberg <penberg@kernel.org>
Diffstat (limited to 'mm/slub.c')
-rw-r--r--mm/slub.c173
1 files changed, 92 insertions, 81 deletions
diff --git a/mm/slub.c b/mm/slub.c
index 8c691fa1cf3c..2de3c996f327 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1490,12 +1490,12 @@ static inline void remove_partial(struct kmem_cache_node *n,
1490} 1490}
1491 1491
1492/* 1492/*
1493 * Lock slab, remove from the partial list and put the object into the 1493 * Remove slab from the partial list, freeze it and
1494 * per cpu freelist. 1494 * return the pointer to the freelist.
1495 * 1495 *
1496 * Returns a list of objects or NULL if it fails. 1496 * Returns a list of objects or NULL if it fails.
1497 * 1497 *
1498 * Must hold list_lock. 1498 * Must hold list_lock since we modify the partial list.
1499 */ 1499 */
1500static inline void *acquire_slab(struct kmem_cache *s, 1500static inline void *acquire_slab(struct kmem_cache *s,
1501 struct kmem_cache_node *n, struct page *page, 1501 struct kmem_cache_node *n, struct page *page,
@@ -1510,26 +1510,27 @@ static inline void *acquire_slab(struct kmem_cache *s,
1510 * The old freelist is the list of objects for the 1510 * The old freelist is the list of objects for the
1511 * per cpu allocation list. 1511 * per cpu allocation list.
1512 */ 1512 */
1513 do { 1513 freelist = page->freelist;
1514 freelist = page->freelist; 1514 counters = page->counters;
1515 counters = page->counters; 1515 new.counters = counters;
1516 new.counters = counters; 1516 if (mode) {
1517 if (mode) { 1517 new.inuse = page->objects;
1518 new.inuse = page->objects; 1518 new.freelist = NULL;
1519 new.freelist = NULL; 1519 } else {
1520 } else { 1520 new.freelist = freelist;
1521 new.freelist = freelist; 1521 }
1522 }
1523 1522
1524 VM_BUG_ON(new.frozen); 1523 VM_BUG_ON(new.frozen);
1525 new.frozen = 1; 1524 new.frozen = 1;
1526 1525
1527 } while (!__cmpxchg_double_slab(s, page, 1526 if (!__cmpxchg_double_slab(s, page,
1528 freelist, counters, 1527 freelist, counters,
1529 new.freelist, new.counters, 1528 new.freelist, new.counters,
1530 "lock and freeze")); 1529 "acquire_slab"))
1530 return NULL;
1531 1531
1532 remove_partial(n, page); 1532 remove_partial(n, page);
1533 WARN_ON(!freelist);
1533 return freelist; 1534 return freelist;
1534} 1535}
1535 1536
@@ -1563,7 +1564,6 @@ static void *get_partial_node(struct kmem_cache *s,
1563 1564
1564 if (!object) { 1565 if (!object) {
1565 c->page = page; 1566 c->page = page;
1566 c->node = page_to_nid(page);
1567 stat(s, ALLOC_FROM_PARTIAL); 1567 stat(s, ALLOC_FROM_PARTIAL);
1568 object = t; 1568 object = t;
1569 available = page->objects - page->inuse; 1569 available = page->objects - page->inuse;
@@ -1731,14 +1731,12 @@ void init_kmem_cache_cpus(struct kmem_cache *s)
1731/* 1731/*
1732 * Remove the cpu slab 1732 * Remove the cpu slab
1733 */ 1733 */
1734static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) 1734static void deactivate_slab(struct kmem_cache *s, struct page *page, void *freelist)
1735{ 1735{
1736 enum slab_modes { M_NONE, M_PARTIAL, M_FULL, M_FREE }; 1736 enum slab_modes { M_NONE, M_PARTIAL, M_FULL, M_FREE };
1737 struct page *page = c->page;
1738 struct kmem_cache_node *n = get_node(s, page_to_nid(page)); 1737 struct kmem_cache_node *n = get_node(s, page_to_nid(page));
1739 int lock = 0; 1738 int lock = 0;
1740 enum slab_modes l = M_NONE, m = M_NONE; 1739 enum slab_modes l = M_NONE, m = M_NONE;
1741 void *freelist;
1742 void *nextfree; 1740 void *nextfree;
1743 int tail = DEACTIVATE_TO_HEAD; 1741 int tail = DEACTIVATE_TO_HEAD;
1744 struct page new; 1742 struct page new;
@@ -1749,11 +1747,6 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
1749 tail = DEACTIVATE_TO_TAIL; 1747 tail = DEACTIVATE_TO_TAIL;
1750 } 1748 }
1751 1749
1752 c->tid = next_tid(c->tid);
1753 c->page = NULL;
1754 freelist = c->freelist;
1755 c->freelist = NULL;
1756
1757 /* 1750 /*
1758 * Stage one: Free all available per cpu objects back 1751 * Stage one: Free all available per cpu objects back
1759 * to the page freelist while it is still frozen. Leave the 1752 * to the page freelist while it is still frozen. Leave the
@@ -2011,7 +2004,11 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
2011static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) 2004static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
2012{ 2005{
2013 stat(s, CPUSLAB_FLUSH); 2006 stat(s, CPUSLAB_FLUSH);
2014 deactivate_slab(s, c); 2007 deactivate_slab(s, c->page, c->freelist);
2008
2009 c->tid = next_tid(c->tid);
2010 c->page = NULL;
2011 c->freelist = NULL;
2015} 2012}
2016 2013
2017/* 2014/*
@@ -2055,10 +2052,10 @@ static void flush_all(struct kmem_cache *s)
2055 * Check if the objects in a per cpu structure fit numa 2052 * Check if the objects in a per cpu structure fit numa
2056 * locality expectations. 2053 * locality expectations.
2057 */ 2054 */
2058static inline int node_match(struct kmem_cache_cpu *c, int node) 2055static inline int node_match(struct page *page, int node)
2059{ 2056{
2060#ifdef CONFIG_NUMA 2057#ifdef CONFIG_NUMA
2061 if (node != NUMA_NO_NODE && c->node != node) 2058 if (node != NUMA_NO_NODE && page_to_nid(page) != node)
2062 return 0; 2059 return 0;
2063#endif 2060#endif
2064 return 1; 2061 return 1;
@@ -2130,10 +2127,16 @@ slab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid)
2130static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags, 2127static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
2131 int node, struct kmem_cache_cpu **pc) 2128 int node, struct kmem_cache_cpu **pc)
2132{ 2129{
2133 void *object; 2130 void *freelist;
2134 struct kmem_cache_cpu *c; 2131 struct kmem_cache_cpu *c = *pc;
2135 struct page *page = new_slab(s, flags, node); 2132 struct page *page;
2133
2134 freelist = get_partial(s, flags, node, c);
2136 2135
2136 if (freelist)
2137 return freelist;
2138
2139 page = new_slab(s, flags, node);
2137 if (page) { 2140 if (page) {
2138 c = __this_cpu_ptr(s->cpu_slab); 2141 c = __this_cpu_ptr(s->cpu_slab);
2139 if (c->page) 2142 if (c->page)
@@ -2143,17 +2146,16 @@ static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
2143 * No other reference to the page yet so we can 2146 * No other reference to the page yet so we can
2144 * muck around with it freely without cmpxchg 2147 * muck around with it freely without cmpxchg
2145 */ 2148 */
2146 object = page->freelist; 2149 freelist = page->freelist;
2147 page->freelist = NULL; 2150 page->freelist = NULL;
2148 2151
2149 stat(s, ALLOC_SLAB); 2152 stat(s, ALLOC_SLAB);
2150 c->node = page_to_nid(page);
2151 c->page = page; 2153 c->page = page;
2152 *pc = c; 2154 *pc = c;
2153 } else 2155 } else
2154 object = NULL; 2156 freelist = NULL;
2155 2157
2156 return object; 2158 return freelist;
2157} 2159}
2158 2160
2159/* 2161/*
@@ -2173,6 +2175,7 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page)
2173 do { 2175 do {
2174 freelist = page->freelist; 2176 freelist = page->freelist;
2175 counters = page->counters; 2177 counters = page->counters;
2178
2176 new.counters = counters; 2179 new.counters = counters;
2177 VM_BUG_ON(!new.frozen); 2180 VM_BUG_ON(!new.frozen);
2178 2181
@@ -2206,7 +2209,8 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page)
2206static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, 2209static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
2207 unsigned long addr, struct kmem_cache_cpu *c) 2210 unsigned long addr, struct kmem_cache_cpu *c)
2208{ 2211{
2209 void **object; 2212 void *freelist;
2213 struct page *page;
2210 unsigned long flags; 2214 unsigned long flags;
2211 2215
2212 local_irq_save(flags); 2216 local_irq_save(flags);
@@ -2219,25 +2223,29 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
2219 c = this_cpu_ptr(s->cpu_slab); 2223 c = this_cpu_ptr(s->cpu_slab);
2220#endif 2224#endif
2221 2225
2222 if (!c->page) 2226 page = c->page;
2227 if (!page)
2223 goto new_slab; 2228 goto new_slab;
2224redo: 2229redo:
2225 if (unlikely(!node_match(c, node))) { 2230
2231 if (unlikely(!node_match(page, node))) {
2226 stat(s, ALLOC_NODE_MISMATCH); 2232 stat(s, ALLOC_NODE_MISMATCH);
2227 deactivate_slab(s, c); 2233 deactivate_slab(s, page, c->freelist);
2234 c->page = NULL;
2235 c->freelist = NULL;
2228 goto new_slab; 2236 goto new_slab;
2229 } 2237 }
2230 2238
2231 /* must check again c->freelist in case of cpu migration or IRQ */ 2239 /* must check again c->freelist in case of cpu migration or IRQ */
2232 object = c->freelist; 2240 freelist = c->freelist;
2233 if (object) 2241 if (freelist)
2234 goto load_freelist; 2242 goto load_freelist;
2235 2243
2236 stat(s, ALLOC_SLOWPATH); 2244 stat(s, ALLOC_SLOWPATH);
2237 2245
2238 object = get_freelist(s, c->page); 2246 freelist = get_freelist(s, page);
2239 2247
2240 if (!object) { 2248 if (!freelist) {
2241 c->page = NULL; 2249 c->page = NULL;
2242 stat(s, DEACTIVATE_BYPASS); 2250 stat(s, DEACTIVATE_BYPASS);
2243 goto new_slab; 2251 goto new_slab;
@@ -2246,50 +2254,50 @@ redo:
2246 stat(s, ALLOC_REFILL); 2254 stat(s, ALLOC_REFILL);
2247 2255
2248load_freelist: 2256load_freelist:
2249 c->freelist = get_freepointer(s, object); 2257 /*
2258 * freelist is pointing to the list of objects to be used.
2259 * page is pointing to the page from which the objects are obtained.
2260 * That page must be frozen for per cpu allocations to work.
2261 */
2262 VM_BUG_ON(!c->page->frozen);
2263 c->freelist = get_freepointer(s, freelist);
2250 c->tid = next_tid(c->tid); 2264 c->tid = next_tid(c->tid);
2251 local_irq_restore(flags); 2265 local_irq_restore(flags);
2252 return object; 2266 return freelist;
2253 2267
2254new_slab: 2268new_slab:
2255 2269
2256 if (c->partial) { 2270 if (c->partial) {
2257 c->page = c->partial; 2271 page = c->page = c->partial;
2258 c->partial = c->page->next; 2272 c->partial = page->next;
2259 c->node = page_to_nid(c->page);
2260 stat(s, CPU_PARTIAL_ALLOC); 2273 stat(s, CPU_PARTIAL_ALLOC);
2261 c->freelist = NULL; 2274 c->freelist = NULL;
2262 goto redo; 2275 goto redo;
2263 } 2276 }
2264 2277
2265 /* Then do expensive stuff like retrieving pages from the partial lists */ 2278 freelist = new_slab_objects(s, gfpflags, node, &c);
2266 object = get_partial(s, gfpflags, node, c);
2267
2268 if (unlikely(!object)) {
2269 2279
2270 object = new_slab_objects(s, gfpflags, node, &c); 2280 if (unlikely(!freelist)) {
2281 if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
2282 slab_out_of_memory(s, gfpflags, node);
2271 2283
2272 if (unlikely(!object)) { 2284 local_irq_restore(flags);
2273 if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit()) 2285 return NULL;
2274 slab_out_of_memory(s, gfpflags, node);
2275
2276 local_irq_restore(flags);
2277 return NULL;
2278 }
2279 } 2286 }
2280 2287
2288 page = c->page;
2281 if (likely(!kmem_cache_debug(s))) 2289 if (likely(!kmem_cache_debug(s)))
2282 goto load_freelist; 2290 goto load_freelist;
2283 2291
2284 /* Only entered in the debug case */ 2292 /* Only entered in the debug case */
2285 if (!alloc_debug_processing(s, c->page, object, addr)) 2293 if (!alloc_debug_processing(s, page, freelist, addr))
2286 goto new_slab; /* Slab failed checks. Next slab needed */ 2294 goto new_slab; /* Slab failed checks. Next slab needed */
2287 2295
2288 c->freelist = get_freepointer(s, object); 2296 deactivate_slab(s, page, get_freepointer(s, freelist));
2289 deactivate_slab(s, c); 2297 c->page = NULL;
2290 c->node = NUMA_NO_NODE; 2298 c->freelist = NULL;
2291 local_irq_restore(flags); 2299 local_irq_restore(flags);
2292 return object; 2300 return freelist;
2293} 2301}
2294 2302
2295/* 2303/*
@@ -2307,6 +2315,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
2307{ 2315{
2308 void **object; 2316 void **object;
2309 struct kmem_cache_cpu *c; 2317 struct kmem_cache_cpu *c;
2318 struct page *page;
2310 unsigned long tid; 2319 unsigned long tid;
2311 2320
2312 if (slab_pre_alloc_hook(s, gfpflags)) 2321 if (slab_pre_alloc_hook(s, gfpflags))
@@ -2332,7 +2341,8 @@ redo:
2332 barrier(); 2341 barrier();
2333 2342
2334 object = c->freelist; 2343 object = c->freelist;
2335 if (unlikely(!object || !node_match(c, node))) 2344 page = c->page;
2345 if (unlikely(!object || !node_match(page, node)))
2336 2346
2337 object = __slab_alloc(s, gfpflags, node, addr, c); 2347 object = __slab_alloc(s, gfpflags, node, addr, c);
2338 2348
@@ -4500,30 +4510,31 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
4500 4510
4501 for_each_possible_cpu(cpu) { 4511 for_each_possible_cpu(cpu) {
4502 struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu); 4512 struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
4503 int node = ACCESS_ONCE(c->node); 4513 int node;
4504 struct page *page; 4514 struct page *page;
4505 4515
4506 if (node < 0)
4507 continue;
4508 page = ACCESS_ONCE(c->page); 4516 page = ACCESS_ONCE(c->page);
4509 if (page) { 4517 if (!page)
4510 if (flags & SO_TOTAL) 4518 continue;
4511 x = page->objects;
4512 else if (flags & SO_OBJECTS)
4513 x = page->inuse;
4514 else
4515 x = 1;
4516 4519
4517 total += x; 4520 node = page_to_nid(page);
4518 nodes[node] += x; 4521 if (flags & SO_TOTAL)
4519 } 4522 x = page->objects;
4520 page = c->partial; 4523 else if (flags & SO_OBJECTS)
4524 x = page->inuse;
4525 else
4526 x = 1;
4521 4527
4528 total += x;
4529 nodes[node] += x;
4530
4531 page = ACCESS_ONCE(c->partial);
4522 if (page) { 4532 if (page) {
4523 x = page->pobjects; 4533 x = page->pobjects;
4524 total += x; 4534 total += x;
4525 nodes[node] += x; 4535 nodes[node] += x;
4526 } 4536 }
4537
4527 per_cpu[node]++; 4538 per_cpu[node]++;
4528 } 4539 }
4529 } 4540 }