Commit 911891afe1c3104adf0f802189909868239ebbfd

Authored by Xiao Guangrong
Committed by Linus Torvalds
1 parent 637e3a27ec

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

... ... @@ -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