diff options
author | Nick Piggin <npiggin@suse.de> | 2009-01-06 17:39:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-06 18:59:01 -0500 |
commit | e97a630eb0f5b8b380fd67504de6cedebb489003 (patch) | |
tree | 52e337eafeb386b97630e7ffe2697550e589afc3 /mm/vmalloc.c | |
parent | 848778483351e90f9a2c587bdbe0c78b17c1e30b (diff) |
mm: vmalloc use mutex for purge
The vmalloc purge lock can be a mutex so we can sleep while a purge is
going on (purge involves a global kernel TLB invalidate, so it can take
quite a while).
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/vmalloc.c')
-rw-r--r-- | mm/vmalloc.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index b62ea569aa43..78689cba178f 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/highmem.h> | 14 | #include <linux/highmem.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/mutex.h> | ||
17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
18 | #include <linux/proc_fs.h> | 19 | #include <linux/proc_fs.h> |
19 | #include <linux/seq_file.h> | 20 | #include <linux/seq_file.h> |
@@ -473,7 +474,7 @@ static atomic_t vmap_lazy_nr = ATOMIC_INIT(0); | |||
473 | static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, | 474 | static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, |
474 | int sync, int force_flush) | 475 | int sync, int force_flush) |
475 | { | 476 | { |
476 | static DEFINE_SPINLOCK(purge_lock); | 477 | static DEFINE_MUTEX(purge_lock); |
477 | LIST_HEAD(valist); | 478 | LIST_HEAD(valist); |
478 | struct vmap_area *va; | 479 | struct vmap_area *va; |
479 | int nr = 0; | 480 | int nr = 0; |
@@ -484,10 +485,10 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, | |||
484 | * the case that isn't actually used at the moment anyway. | 485 | * the case that isn't actually used at the moment anyway. |
485 | */ | 486 | */ |
486 | if (!sync && !force_flush) { | 487 | if (!sync && !force_flush) { |
487 | if (!spin_trylock(&purge_lock)) | 488 | if (!mutex_trylock(&purge_lock)) |
488 | return; | 489 | return; |
489 | } else | 490 | } else |
490 | spin_lock(&purge_lock); | 491 | mutex_lock(&purge_lock); |
491 | 492 | ||
492 | rcu_read_lock(); | 493 | rcu_read_lock(); |
493 | list_for_each_entry_rcu(va, &vmap_area_list, list) { | 494 | list_for_each_entry_rcu(va, &vmap_area_list, list) { |
@@ -519,7 +520,7 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end, | |||
519 | __free_vmap_area(va); | 520 | __free_vmap_area(va); |
520 | spin_unlock(&vmap_area_lock); | 521 | spin_unlock(&vmap_area_lock); |
521 | } | 522 | } |
522 | spin_unlock(&purge_lock); | 523 | mutex_unlock(&purge_lock); |
523 | } | 524 | } |
524 | 525 | ||
525 | /* | 526 | /* |