diff options
Diffstat (limited to 'include/linux/rmap.h')
-rw-r--r-- | include/linux/rmap.h | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/include/linux/rmap.h b/include/linux/rmap.h index bfe1f4780644..c20635c527a9 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <linux/list.h> | 7 | #include <linux/list.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/mutex.h> | 10 | #include <linux/rwsem.h> |
11 | #include <linux/memcontrol.h> | 11 | #include <linux/memcontrol.h> |
12 | 12 | ||
13 | /* | 13 | /* |
@@ -25,8 +25,8 @@ | |||
25 | * pointing to this anon_vma once its vma list is empty. | 25 | * pointing to this anon_vma once its vma list is empty. |
26 | */ | 26 | */ |
27 | struct anon_vma { | 27 | struct anon_vma { |
28 | struct anon_vma *root; /* Root of this anon_vma tree */ | 28 | struct anon_vma *root; /* Root of this anon_vma tree */ |
29 | struct mutex mutex; /* Serialize access to vma list */ | 29 | struct rw_semaphore rwsem; /* W: modification, R: walking the list */ |
30 | /* | 30 | /* |
31 | * The refcount is taken on an anon_vma when there is no | 31 | * The refcount is taken on an anon_vma when there is no |
32 | * guarantee that the vma of page tables will exist for | 32 | * guarantee that the vma of page tables will exist for |
@@ -64,7 +64,7 @@ struct anon_vma_chain { | |||
64 | struct vm_area_struct *vma; | 64 | struct vm_area_struct *vma; |
65 | struct anon_vma *anon_vma; | 65 | struct anon_vma *anon_vma; |
66 | struct list_head same_vma; /* locked by mmap_sem & page_table_lock */ | 66 | struct list_head same_vma; /* locked by mmap_sem & page_table_lock */ |
67 | struct rb_node rb; /* locked by anon_vma->mutex */ | 67 | struct rb_node rb; /* locked by anon_vma->rwsem */ |
68 | unsigned long rb_subtree_last; | 68 | unsigned long rb_subtree_last; |
69 | #ifdef CONFIG_DEBUG_VM_RB | 69 | #ifdef CONFIG_DEBUG_VM_RB |
70 | unsigned long cached_vma_start, cached_vma_last; | 70 | unsigned long cached_vma_start, cached_vma_last; |
@@ -108,26 +108,37 @@ static inline void vma_lock_anon_vma(struct vm_area_struct *vma) | |||
108 | { | 108 | { |
109 | struct anon_vma *anon_vma = vma->anon_vma; | 109 | struct anon_vma *anon_vma = vma->anon_vma; |
110 | if (anon_vma) | 110 | if (anon_vma) |
111 | mutex_lock(&anon_vma->root->mutex); | 111 | down_write(&anon_vma->root->rwsem); |
112 | } | 112 | } |
113 | 113 | ||
114 | static inline void vma_unlock_anon_vma(struct vm_area_struct *vma) | 114 | static inline void vma_unlock_anon_vma(struct vm_area_struct *vma) |
115 | { | 115 | { |
116 | struct anon_vma *anon_vma = vma->anon_vma; | 116 | struct anon_vma *anon_vma = vma->anon_vma; |
117 | if (anon_vma) | 117 | if (anon_vma) |
118 | mutex_unlock(&anon_vma->root->mutex); | 118 | up_write(&anon_vma->root->rwsem); |
119 | } | 119 | } |
120 | 120 | ||
121 | static inline void anon_vma_lock(struct anon_vma *anon_vma) | 121 | static inline void anon_vma_lock_write(struct anon_vma *anon_vma) |
122 | { | 122 | { |
123 | mutex_lock(&anon_vma->root->mutex); | 123 | down_write(&anon_vma->root->rwsem); |
124 | } | 124 | } |
125 | 125 | ||
126 | static inline void anon_vma_unlock(struct anon_vma *anon_vma) | 126 | static inline void anon_vma_unlock(struct anon_vma *anon_vma) |
127 | { | 127 | { |
128 | mutex_unlock(&anon_vma->root->mutex); | 128 | up_write(&anon_vma->root->rwsem); |
129 | } | 129 | } |
130 | 130 | ||
131 | static inline void anon_vma_lock_read(struct anon_vma *anon_vma) | ||
132 | { | ||
133 | down_read(&anon_vma->root->rwsem); | ||
134 | } | ||
135 | |||
136 | static inline void anon_vma_unlock_read(struct anon_vma *anon_vma) | ||
137 | { | ||
138 | up_read(&anon_vma->root->rwsem); | ||
139 | } | ||
140 | |||
141 | |||
131 | /* | 142 | /* |
132 | * anon_vma helper functions. | 143 | * anon_vma helper functions. |
133 | */ | 144 | */ |
@@ -220,8 +231,8 @@ int try_to_munlock(struct page *); | |||
220 | /* | 231 | /* |
221 | * Called by memory-failure.c to kill processes. | 232 | * Called by memory-failure.c to kill processes. |
222 | */ | 233 | */ |
223 | struct anon_vma *page_lock_anon_vma(struct page *page); | 234 | struct anon_vma *page_lock_anon_vma_read(struct page *page); |
224 | void page_unlock_anon_vma(struct anon_vma *anon_vma); | 235 | void page_unlock_anon_vma_read(struct anon_vma *anon_vma); |
225 | int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma); | 236 | int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma); |
226 | 237 | ||
227 | /* | 238 | /* |