Commit 911891afe1c3104adf0f802189909868239ebbfd
Committed by
Linus Torvalds
1 parent
637e3a27ec
Exists in
master
and in
20 other branches
thp: move khugepaged_mutex out of khugepaged
Currently, hugepaged_mutex is used really complexly and hard to understand, actually, it is just used to serialize start_khugepaged and khugepaged for these reasons: - khugepaged_thread is shared between them - the thp disable path (echo never > transparent_hugepage/enabled) is nonblocking, so we need to protect khugepaged_thread to get a stable running state These can be avoided by: - use the lock to serialize the thread creation and cancel - thp disable path can not finised until the thread exits Then khugepaged_thread is fully controlled by start_khugepaged, khugepaged will be happy without the lock Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Hugh Dickins <hughd@google.com> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 13 additions and 23 deletions Side-by-side Diff
mm/huge_memory.c
... | ... | @@ -139,9 +139,6 @@ |
139 | 139 | { |
140 | 140 | int err = 0; |
141 | 141 | if (khugepaged_enabled()) { |
142 | - int wakeup; | |
143 | - | |
144 | - mutex_lock(&khugepaged_mutex); | |
145 | 142 | if (!khugepaged_thread) |
146 | 143 | khugepaged_thread = kthread_run(khugepaged, NULL, |
147 | 144 | "khugepaged"); |
148 | 145 | |
149 | 146 | |
... | ... | @@ -151,15 +148,17 @@ |
151 | 148 | err = PTR_ERR(khugepaged_thread); |
152 | 149 | khugepaged_thread = NULL; |
153 | 150 | } |
154 | - wakeup = !list_empty(&khugepaged_scan.mm_head); | |
155 | - mutex_unlock(&khugepaged_mutex); | |
156 | - if (wakeup) | |
151 | + | |
152 | + if (!list_empty(&khugepaged_scan.mm_head)) | |
157 | 153 | wake_up_interruptible(&khugepaged_wait); |
158 | 154 | |
159 | 155 | set_recommended_min_free_kbytes(); |
160 | - } else | |
156 | + } else if (khugepaged_thread) { | |
161 | 157 | /* wakeup to exit */ |
162 | 158 | wake_up_interruptible(&khugepaged_wait); |
159 | + kthread_stop(khugepaged_thread); | |
160 | + khugepaged_thread = NULL; | |
161 | + } | |
163 | 162 | |
164 | 163 | return err; |
165 | 164 | } |
... | ... | @@ -221,7 +220,12 @@ |
221 | 220 | TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG); |
222 | 221 | |
223 | 222 | if (ret > 0) { |
224 | - int err = start_khugepaged(); | |
223 | + int err; | |
224 | + | |
225 | + mutex_lock(&khugepaged_mutex); | |
226 | + err = start_khugepaged(); | |
227 | + mutex_unlock(&khugepaged_mutex); | |
228 | + | |
225 | 229 | if (err) |
226 | 230 | ret = err; |
227 | 231 | } |
228 | 232 | |
... | ... | @@ -2329,20 +2333,10 @@ |
2329 | 2333 | set_freezable(); |
2330 | 2334 | set_user_nice(current, 19); |
2331 | 2335 | |
2332 | - /* serialize with start_khugepaged() */ | |
2333 | - mutex_lock(&khugepaged_mutex); | |
2334 | - | |
2335 | - for (;;) { | |
2336 | - mutex_unlock(&khugepaged_mutex); | |
2336 | + while (!kthread_should_stop()) { | |
2337 | 2337 | VM_BUG_ON(khugepaged_thread != current); |
2338 | 2338 | khugepaged_loop(); |
2339 | 2339 | VM_BUG_ON(khugepaged_thread != current); |
2340 | - | |
2341 | - mutex_lock(&khugepaged_mutex); | |
2342 | - if (!khugepaged_enabled()) | |
2343 | - break; | |
2344 | - if (unlikely(kthread_should_stop())) | |
2345 | - break; | |
2346 | 2340 | } |
2347 | 2341 | |
2348 | 2342 | spin_lock(&khugepaged_mm_lock); |
... | ... | @@ -2351,10 +2345,6 @@ |
2351 | 2345 | if (mm_slot) |
2352 | 2346 | collect_mm_slot(mm_slot); |
2353 | 2347 | spin_unlock(&khugepaged_mm_lock); |
2354 | - | |
2355 | - khugepaged_thread = NULL; | |
2356 | - mutex_unlock(&khugepaged_mutex); | |
2357 | - | |
2358 | 2348 | return 0; |
2359 | 2349 | } |
2360 | 2350 |