diff options
Diffstat (limited to 'mm/slab.c')
-rw-r--r-- | mm/slab.c | 18 |
1 files changed, 11 insertions, 7 deletions
@@ -730,8 +730,7 @@ static inline void init_lock_keys(void) | |||
730 | #endif | 730 | #endif |
731 | 731 | ||
732 | /* | 732 | /* |
733 | * 1. Guard access to the cache-chain. | 733 | * Guard access to the cache-chain. |
734 | * 2. Protect sanity of cpu_online_map against cpu hotplug events | ||
735 | */ | 734 | */ |
736 | static DEFINE_MUTEX(cache_chain_mutex); | 735 | static DEFINE_MUTEX(cache_chain_mutex); |
737 | static struct list_head cache_chain; | 736 | static struct list_head cache_chain; |
@@ -1331,12 +1330,11 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, | |||
1331 | int err = 0; | 1330 | int err = 0; |
1332 | 1331 | ||
1333 | switch (action) { | 1332 | switch (action) { |
1334 | case CPU_LOCK_ACQUIRE: | ||
1335 | mutex_lock(&cache_chain_mutex); | ||
1336 | break; | ||
1337 | case CPU_UP_PREPARE: | 1333 | case CPU_UP_PREPARE: |
1338 | case CPU_UP_PREPARE_FROZEN: | 1334 | case CPU_UP_PREPARE_FROZEN: |
1335 | mutex_lock(&cache_chain_mutex); | ||
1339 | err = cpuup_prepare(cpu); | 1336 | err = cpuup_prepare(cpu); |
1337 | mutex_unlock(&cache_chain_mutex); | ||
1340 | break; | 1338 | break; |
1341 | case CPU_ONLINE: | 1339 | case CPU_ONLINE: |
1342 | case CPU_ONLINE_FROZEN: | 1340 | case CPU_ONLINE_FROZEN: |
@@ -1373,9 +1371,8 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, | |||
1373 | #endif | 1371 | #endif |
1374 | case CPU_UP_CANCELED: | 1372 | case CPU_UP_CANCELED: |
1375 | case CPU_UP_CANCELED_FROZEN: | 1373 | case CPU_UP_CANCELED_FROZEN: |
1374 | mutex_lock(&cache_chain_mutex); | ||
1376 | cpuup_canceled(cpu); | 1375 | cpuup_canceled(cpu); |
1377 | break; | ||
1378 | case CPU_LOCK_RELEASE: | ||
1379 | mutex_unlock(&cache_chain_mutex); | 1376 | mutex_unlock(&cache_chain_mutex); |
1380 | break; | 1377 | break; |
1381 | } | 1378 | } |
@@ -2170,6 +2167,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
2170 | * We use cache_chain_mutex to ensure a consistent view of | 2167 | * We use cache_chain_mutex to ensure a consistent view of |
2171 | * cpu_online_map as well. Please see cpuup_callback | 2168 | * cpu_online_map as well. Please see cpuup_callback |
2172 | */ | 2169 | */ |
2170 | get_online_cpus(); | ||
2173 | mutex_lock(&cache_chain_mutex); | 2171 | mutex_lock(&cache_chain_mutex); |
2174 | 2172 | ||
2175 | list_for_each_entry(pc, &cache_chain, next) { | 2173 | list_for_each_entry(pc, &cache_chain, next) { |
@@ -2396,6 +2394,7 @@ oops: | |||
2396 | panic("kmem_cache_create(): failed to create slab `%s'\n", | 2394 | panic("kmem_cache_create(): failed to create slab `%s'\n", |
2397 | name); | 2395 | name); |
2398 | mutex_unlock(&cache_chain_mutex); | 2396 | mutex_unlock(&cache_chain_mutex); |
2397 | put_online_cpus(); | ||
2399 | return cachep; | 2398 | return cachep; |
2400 | } | 2399 | } |
2401 | EXPORT_SYMBOL(kmem_cache_create); | 2400 | EXPORT_SYMBOL(kmem_cache_create); |
@@ -2547,9 +2546,11 @@ int kmem_cache_shrink(struct kmem_cache *cachep) | |||
2547 | int ret; | 2546 | int ret; |
2548 | BUG_ON(!cachep || in_interrupt()); | 2547 | BUG_ON(!cachep || in_interrupt()); |
2549 | 2548 | ||
2549 | get_online_cpus(); | ||
2550 | mutex_lock(&cache_chain_mutex); | 2550 | mutex_lock(&cache_chain_mutex); |
2551 | ret = __cache_shrink(cachep); | 2551 | ret = __cache_shrink(cachep); |
2552 | mutex_unlock(&cache_chain_mutex); | 2552 | mutex_unlock(&cache_chain_mutex); |
2553 | put_online_cpus(); | ||
2553 | return ret; | 2554 | return ret; |
2554 | } | 2555 | } |
2555 | EXPORT_SYMBOL(kmem_cache_shrink); | 2556 | EXPORT_SYMBOL(kmem_cache_shrink); |
@@ -2575,6 +2576,7 @@ void kmem_cache_destroy(struct kmem_cache *cachep) | |||
2575 | BUG_ON(!cachep || in_interrupt()); | 2576 | BUG_ON(!cachep || in_interrupt()); |
2576 | 2577 | ||
2577 | /* Find the cache in the chain of caches. */ | 2578 | /* Find the cache in the chain of caches. */ |
2579 | get_online_cpus(); | ||
2578 | mutex_lock(&cache_chain_mutex); | 2580 | mutex_lock(&cache_chain_mutex); |
2579 | /* | 2581 | /* |
2580 | * the chain is never empty, cache_cache is never destroyed | 2582 | * the chain is never empty, cache_cache is never destroyed |
@@ -2584,6 +2586,7 @@ void kmem_cache_destroy(struct kmem_cache *cachep) | |||
2584 | slab_error(cachep, "Can't free all objects"); | 2586 | slab_error(cachep, "Can't free all objects"); |
2585 | list_add(&cachep->next, &cache_chain); | 2587 | list_add(&cachep->next, &cache_chain); |
2586 | mutex_unlock(&cache_chain_mutex); | 2588 | mutex_unlock(&cache_chain_mutex); |
2589 | put_online_cpus(); | ||
2587 | return; | 2590 | return; |
2588 | } | 2591 | } |
2589 | 2592 | ||
@@ -2592,6 +2595,7 @@ void kmem_cache_destroy(struct kmem_cache *cachep) | |||
2592 | 2595 | ||
2593 | __kmem_cache_destroy(cachep); | 2596 | __kmem_cache_destroy(cachep); |
2594 | mutex_unlock(&cache_chain_mutex); | 2597 | mutex_unlock(&cache_chain_mutex); |
2598 | put_online_cpus(); | ||
2595 | } | 2599 | } |
2596 | EXPORT_SYMBOL(kmem_cache_destroy); | 2600 | EXPORT_SYMBOL(kmem_cache_destroy); |
2597 | 2601 | ||