diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/slab.c | 46 | ||||
-rw-r--r-- | mm/swapfile.c | 17 |
2 files changed, 32 insertions, 31 deletions
@@ -68,7 +68,7 @@ | |||
68 | * Further notes from the original documentation: | 68 | * Further notes from the original documentation: |
69 | * | 69 | * |
70 | * 11 April '97. Started multi-threading - markhe | 70 | * 11 April '97. Started multi-threading - markhe |
71 | * The global cache-chain is protected by the semaphore 'cache_chain_sem'. | 71 | * The global cache-chain is protected by the mutex 'cache_chain_mutex'. |
72 | * The sem is only needed when accessing/extending the cache-chain, which | 72 | * The sem is only needed when accessing/extending the cache-chain, which |
73 | * can never happen inside an interrupt (kmem_cache_create(), | 73 | * can never happen inside an interrupt (kmem_cache_create(), |
74 | * kmem_cache_shrink() and kmem_cache_reap()). | 74 | * kmem_cache_shrink() and kmem_cache_reap()). |
@@ -103,6 +103,7 @@ | |||
103 | #include <linux/rcupdate.h> | 103 | #include <linux/rcupdate.h> |
104 | #include <linux/string.h> | 104 | #include <linux/string.h> |
105 | #include <linux/nodemask.h> | 105 | #include <linux/nodemask.h> |
106 | #include <linux/mutex.h> | ||
106 | 107 | ||
107 | #include <asm/uaccess.h> | 108 | #include <asm/uaccess.h> |
108 | #include <asm/cacheflush.h> | 109 | #include <asm/cacheflush.h> |
@@ -631,7 +632,7 @@ static kmem_cache_t cache_cache = { | |||
631 | }; | 632 | }; |
632 | 633 | ||
633 | /* Guard access to the cache-chain. */ | 634 | /* Guard access to the cache-chain. */ |
634 | static struct semaphore cache_chain_sem; | 635 | static DEFINE_MUTEX(cache_chain_mutex); |
635 | static struct list_head cache_chain; | 636 | static struct list_head cache_chain; |
636 | 637 | ||
637 | /* | 638 | /* |
@@ -857,7 +858,7 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
857 | 858 | ||
858 | switch (action) { | 859 | switch (action) { |
859 | case CPU_UP_PREPARE: | 860 | case CPU_UP_PREPARE: |
860 | down(&cache_chain_sem); | 861 | mutex_lock(&cache_chain_mutex); |
861 | /* we need to do this right in the beginning since | 862 | /* we need to do this right in the beginning since |
862 | * alloc_arraycache's are going to use this list. | 863 | * alloc_arraycache's are going to use this list. |
863 | * kmalloc_node allows us to add the slab to the right | 864 | * kmalloc_node allows us to add the slab to the right |
@@ -912,7 +913,7 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
912 | l3->shared = nc; | 913 | l3->shared = nc; |
913 | } | 914 | } |
914 | } | 915 | } |
915 | up(&cache_chain_sem); | 916 | mutex_unlock(&cache_chain_mutex); |
916 | break; | 917 | break; |
917 | case CPU_ONLINE: | 918 | case CPU_ONLINE: |
918 | start_cpu_timer(cpu); | 919 | start_cpu_timer(cpu); |
@@ -921,7 +922,7 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
921 | case CPU_DEAD: | 922 | case CPU_DEAD: |
922 | /* fall thru */ | 923 | /* fall thru */ |
923 | case CPU_UP_CANCELED: | 924 | case CPU_UP_CANCELED: |
924 | down(&cache_chain_sem); | 925 | mutex_lock(&cache_chain_mutex); |
925 | 926 | ||
926 | list_for_each_entry(cachep, &cache_chain, next) { | 927 | list_for_each_entry(cachep, &cache_chain, next) { |
927 | struct array_cache *nc; | 928 | struct array_cache *nc; |
@@ -973,13 +974,13 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
973 | spin_unlock_irq(&cachep->spinlock); | 974 | spin_unlock_irq(&cachep->spinlock); |
974 | kfree(nc); | 975 | kfree(nc); |
975 | } | 976 | } |
976 | up(&cache_chain_sem); | 977 | mutex_unlock(&cache_chain_mutex); |
977 | break; | 978 | break; |
978 | #endif | 979 | #endif |
979 | } | 980 | } |
980 | return NOTIFY_OK; | 981 | return NOTIFY_OK; |
981 | bad: | 982 | bad: |
982 | up(&cache_chain_sem); | 983 | mutex_unlock(&cache_chain_mutex); |
983 | return NOTIFY_BAD; | 984 | return NOTIFY_BAD; |
984 | } | 985 | } |
985 | 986 | ||
@@ -1047,7 +1048,6 @@ void __init kmem_cache_init(void) | |||
1047 | */ | 1048 | */ |
1048 | 1049 | ||
1049 | /* 1) create the cache_cache */ | 1050 | /* 1) create the cache_cache */ |
1050 | init_MUTEX(&cache_chain_sem); | ||
1051 | INIT_LIST_HEAD(&cache_chain); | 1051 | INIT_LIST_HEAD(&cache_chain); |
1052 | list_add(&cache_cache.next, &cache_chain); | 1052 | list_add(&cache_cache.next, &cache_chain); |
1053 | cache_cache.colour_off = cache_line_size(); | 1053 | cache_cache.colour_off = cache_line_size(); |
@@ -1168,10 +1168,10 @@ void __init kmem_cache_init(void) | |||
1168 | /* 6) resize the head arrays to their final sizes */ | 1168 | /* 6) resize the head arrays to their final sizes */ |
1169 | { | 1169 | { |
1170 | kmem_cache_t *cachep; | 1170 | kmem_cache_t *cachep; |
1171 | down(&cache_chain_sem); | 1171 | mutex_lock(&cache_chain_mutex); |
1172 | list_for_each_entry(cachep, &cache_chain, next) | 1172 | list_for_each_entry(cachep, &cache_chain, next) |
1173 | enable_cpucache(cachep); | 1173 | enable_cpucache(cachep); |
1174 | up(&cache_chain_sem); | 1174 | mutex_unlock(&cache_chain_mutex); |
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | /* Done! */ | 1177 | /* Done! */ |
@@ -1590,7 +1590,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
1590 | BUG(); | 1590 | BUG(); |
1591 | } | 1591 | } |
1592 | 1592 | ||
1593 | down(&cache_chain_sem); | 1593 | mutex_lock(&cache_chain_mutex); |
1594 | 1594 | ||
1595 | list_for_each(p, &cache_chain) { | 1595 | list_for_each(p, &cache_chain) { |
1596 | kmem_cache_t *pc = list_entry(p, kmem_cache_t, next); | 1596 | kmem_cache_t *pc = list_entry(p, kmem_cache_t, next); |
@@ -1856,7 +1856,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
1856 | if (!cachep && (flags & SLAB_PANIC)) | 1856 | if (!cachep && (flags & SLAB_PANIC)) |
1857 | panic("kmem_cache_create(): failed to create slab `%s'\n", | 1857 | panic("kmem_cache_create(): failed to create slab `%s'\n", |
1858 | name); | 1858 | name); |
1859 | up(&cache_chain_sem); | 1859 | mutex_unlock(&cache_chain_mutex); |
1860 | return cachep; | 1860 | return cachep; |
1861 | } | 1861 | } |
1862 | EXPORT_SYMBOL(kmem_cache_create); | 1862 | EXPORT_SYMBOL(kmem_cache_create); |
@@ -2044,18 +2044,18 @@ int kmem_cache_destroy(kmem_cache_t *cachep) | |||
2044 | lock_cpu_hotplug(); | 2044 | lock_cpu_hotplug(); |
2045 | 2045 | ||
2046 | /* Find the cache in the chain of caches. */ | 2046 | /* Find the cache in the chain of caches. */ |
2047 | down(&cache_chain_sem); | 2047 | mutex_lock(&cache_chain_mutex); |
2048 | /* | 2048 | /* |
2049 | * the chain is never empty, cache_cache is never destroyed | 2049 | * the chain is never empty, cache_cache is never destroyed |
2050 | */ | 2050 | */ |
2051 | list_del(&cachep->next); | 2051 | list_del(&cachep->next); |
2052 | up(&cache_chain_sem); | 2052 | mutex_unlock(&cache_chain_mutex); |
2053 | 2053 | ||
2054 | if (__cache_shrink(cachep)) { | 2054 | if (__cache_shrink(cachep)) { |
2055 | slab_error(cachep, "Can't free all objects"); | 2055 | slab_error(cachep, "Can't free all objects"); |
2056 | down(&cache_chain_sem); | 2056 | mutex_lock(&cache_chain_mutex); |
2057 | list_add(&cachep->next, &cache_chain); | 2057 | list_add(&cachep->next, &cache_chain); |
2058 | up(&cache_chain_sem); | 2058 | mutex_unlock(&cache_chain_mutex); |
2059 | unlock_cpu_hotplug(); | 2059 | unlock_cpu_hotplug(); |
2060 | return 1; | 2060 | return 1; |
2061 | } | 2061 | } |
@@ -3314,7 +3314,7 @@ static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac, | |||
3314 | * - clear the per-cpu caches for this CPU. | 3314 | * - clear the per-cpu caches for this CPU. |
3315 | * - return freeable pages to the main free memory pool. | 3315 | * - return freeable pages to the main free memory pool. |
3316 | * | 3316 | * |
3317 | * If we cannot acquire the cache chain semaphore then just give up - we'll | 3317 | * If we cannot acquire the cache chain mutex then just give up - we'll |
3318 | * try again on the next iteration. | 3318 | * try again on the next iteration. |
3319 | */ | 3319 | */ |
3320 | static void cache_reap(void *unused) | 3320 | static void cache_reap(void *unused) |
@@ -3322,7 +3322,7 @@ static void cache_reap(void *unused) | |||
3322 | struct list_head *walk; | 3322 | struct list_head *walk; |
3323 | struct kmem_list3 *l3; | 3323 | struct kmem_list3 *l3; |
3324 | 3324 | ||
3325 | if (down_trylock(&cache_chain_sem)) { | 3325 | if (!mutex_trylock(&cache_chain_mutex)) { |
3326 | /* Give up. Setup the next iteration. */ | 3326 | /* Give up. Setup the next iteration. */ |
3327 | schedule_delayed_work(&__get_cpu_var(reap_work), | 3327 | schedule_delayed_work(&__get_cpu_var(reap_work), |
3328 | REAPTIMEOUT_CPUC); | 3328 | REAPTIMEOUT_CPUC); |
@@ -3393,7 +3393,7 @@ static void cache_reap(void *unused) | |||
3393 | cond_resched(); | 3393 | cond_resched(); |
3394 | } | 3394 | } |
3395 | check_irq_on(); | 3395 | check_irq_on(); |
3396 | up(&cache_chain_sem); | 3396 | mutex_unlock(&cache_chain_mutex); |
3397 | drain_remote_pages(); | 3397 | drain_remote_pages(); |
3398 | /* Setup the next iteration */ | 3398 | /* Setup the next iteration */ |
3399 | schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC); | 3399 | schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC); |
@@ -3429,7 +3429,7 @@ static void *s_start(struct seq_file *m, loff_t *pos) | |||
3429 | loff_t n = *pos; | 3429 | loff_t n = *pos; |
3430 | struct list_head *p; | 3430 | struct list_head *p; |
3431 | 3431 | ||
3432 | down(&cache_chain_sem); | 3432 | mutex_lock(&cache_chain_mutex); |
3433 | if (!n) | 3433 | if (!n) |
3434 | print_slabinfo_header(m); | 3434 | print_slabinfo_header(m); |
3435 | p = cache_chain.next; | 3435 | p = cache_chain.next; |
@@ -3451,7 +3451,7 @@ static void *s_next(struct seq_file *m, void *p, loff_t *pos) | |||
3451 | 3451 | ||
3452 | static void s_stop(struct seq_file *m, void *p) | 3452 | static void s_stop(struct seq_file *m, void *p) |
3453 | { | 3453 | { |
3454 | up(&cache_chain_sem); | 3454 | mutex_unlock(&cache_chain_mutex); |
3455 | } | 3455 | } |
3456 | 3456 | ||
3457 | static int s_show(struct seq_file *m, void *p) | 3457 | static int s_show(struct seq_file *m, void *p) |
@@ -3603,7 +3603,7 @@ ssize_t slabinfo_write(struct file *file, const char __user * buffer, | |||
3603 | return -EINVAL; | 3603 | return -EINVAL; |
3604 | 3604 | ||
3605 | /* Find the cache in the chain of caches. */ | 3605 | /* Find the cache in the chain of caches. */ |
3606 | down(&cache_chain_sem); | 3606 | mutex_lock(&cache_chain_mutex); |
3607 | res = -EINVAL; | 3607 | res = -EINVAL; |
3608 | list_for_each(p, &cache_chain) { | 3608 | list_for_each(p, &cache_chain) { |
3609 | kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next); | 3609 | kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next); |
@@ -3620,7 +3620,7 @@ ssize_t slabinfo_write(struct file *file, const char __user * buffer, | |||
3620 | break; | 3620 | break; |
3621 | } | 3621 | } |
3622 | } | 3622 | } |
3623 | up(&cache_chain_sem); | 3623 | mutex_unlock(&cache_chain_mutex); |
3624 | if (res >= 0) | 3624 | if (res >= 0) |
3625 | res = count; | 3625 | res = count; |
3626 | return res; | 3626 | return res; |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 957fef43fa60..f1e69c30d203 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/rmap.h> | 25 | #include <linux/rmap.h> |
26 | #include <linux/security.h> | 26 | #include <linux/security.h> |
27 | #include <linux/backing-dev.h> | 27 | #include <linux/backing-dev.h> |
28 | #include <linux/mutex.h> | ||
28 | #include <linux/capability.h> | 29 | #include <linux/capability.h> |
29 | #include <linux/syscalls.h> | 30 | #include <linux/syscalls.h> |
30 | 31 | ||
@@ -46,12 +47,12 @@ struct swap_list_t swap_list = {-1, -1}; | |||
46 | 47 | ||
47 | struct swap_info_struct swap_info[MAX_SWAPFILES]; | 48 | struct swap_info_struct swap_info[MAX_SWAPFILES]; |
48 | 49 | ||
49 | static DECLARE_MUTEX(swapon_sem); | 50 | static DEFINE_MUTEX(swapon_mutex); |
50 | 51 | ||
51 | /* | 52 | /* |
52 | * We need this because the bdev->unplug_fn can sleep and we cannot | 53 | * We need this because the bdev->unplug_fn can sleep and we cannot |
53 | * hold swap_lock while calling the unplug_fn. And swap_lock | 54 | * hold swap_lock while calling the unplug_fn. And swap_lock |
54 | * cannot be turned into a semaphore. | 55 | * cannot be turned into a mutex. |
55 | */ | 56 | */ |
56 | static DECLARE_RWSEM(swap_unplug_sem); | 57 | static DECLARE_RWSEM(swap_unplug_sem); |
57 | 58 | ||
@@ -1161,7 +1162,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile) | |||
1161 | up_write(&swap_unplug_sem); | 1162 | up_write(&swap_unplug_sem); |
1162 | 1163 | ||
1163 | destroy_swap_extents(p); | 1164 | destroy_swap_extents(p); |
1164 | down(&swapon_sem); | 1165 | mutex_lock(&swapon_mutex); |
1165 | spin_lock(&swap_lock); | 1166 | spin_lock(&swap_lock); |
1166 | drain_mmlist(); | 1167 | drain_mmlist(); |
1167 | 1168 | ||
@@ -1180,7 +1181,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile) | |||
1180 | p->swap_map = NULL; | 1181 | p->swap_map = NULL; |
1181 | p->flags = 0; | 1182 | p->flags = 0; |
1182 | spin_unlock(&swap_lock); | 1183 | spin_unlock(&swap_lock); |
1183 | up(&swapon_sem); | 1184 | mutex_unlock(&swapon_mutex); |
1184 | vfree(swap_map); | 1185 | vfree(swap_map); |
1185 | inode = mapping->host; | 1186 | inode = mapping->host; |
1186 | if (S_ISBLK(inode->i_mode)) { | 1187 | if (S_ISBLK(inode->i_mode)) { |
@@ -1209,7 +1210,7 @@ static void *swap_start(struct seq_file *swap, loff_t *pos) | |||
1209 | int i; | 1210 | int i; |
1210 | loff_t l = *pos; | 1211 | loff_t l = *pos; |
1211 | 1212 | ||
1212 | down(&swapon_sem); | 1213 | mutex_lock(&swapon_mutex); |
1213 | 1214 | ||
1214 | for (i = 0; i < nr_swapfiles; i++, ptr++) { | 1215 | for (i = 0; i < nr_swapfiles; i++, ptr++) { |
1215 | if (!(ptr->flags & SWP_USED) || !ptr->swap_map) | 1216 | if (!(ptr->flags & SWP_USED) || !ptr->swap_map) |
@@ -1238,7 +1239,7 @@ static void *swap_next(struct seq_file *swap, void *v, loff_t *pos) | |||
1238 | 1239 | ||
1239 | static void swap_stop(struct seq_file *swap, void *v) | 1240 | static void swap_stop(struct seq_file *swap, void *v) |
1240 | { | 1241 | { |
1241 | up(&swapon_sem); | 1242 | mutex_unlock(&swapon_mutex); |
1242 | } | 1243 | } |
1243 | 1244 | ||
1244 | static int swap_show(struct seq_file *swap, void *v) | 1245 | static int swap_show(struct seq_file *swap, void *v) |
@@ -1540,7 +1541,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) | |||
1540 | goto bad_swap; | 1541 | goto bad_swap; |
1541 | } | 1542 | } |
1542 | 1543 | ||
1543 | down(&swapon_sem); | 1544 | mutex_lock(&swapon_mutex); |
1544 | spin_lock(&swap_lock); | 1545 | spin_lock(&swap_lock); |
1545 | p->flags = SWP_ACTIVE; | 1546 | p->flags = SWP_ACTIVE; |
1546 | nr_swap_pages += nr_good_pages; | 1547 | nr_swap_pages += nr_good_pages; |
@@ -1566,7 +1567,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) | |||
1566 | swap_info[prev].next = p - swap_info; | 1567 | swap_info[prev].next = p - swap_info; |
1567 | } | 1568 | } |
1568 | spin_unlock(&swap_lock); | 1569 | spin_unlock(&swap_lock); |
1569 | up(&swapon_sem); | 1570 | mutex_unlock(&swapon_mutex); |
1570 | error = 0; | 1571 | error = 0; |
1571 | goto out; | 1572 | goto out; |
1572 | bad_swap: | 1573 | bad_swap: |