From: kernel test robot <lkp@intel.com>
To: kbuild-all@lists.01.org
Subject: Re: [PATCH 2/5] swap: fix do_swap_page() race with swapoff
Date: Fri, 09 Apr 2021 05:37:07 +0800 [thread overview]
Message-ID: <202104090509.oCjbls7L-lkp@intel.com> (raw)
In-Reply-To: <20210408130820.48233-3-linmiaohe@huawei.com>
[-- Attachment #1: Type: text/plain, Size: 11460 bytes --]
Hi Miaohe,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on linux/master]
[also build test ERROR on linus/master hnaz-linux-mm/master v5.12-rc6 next-20210408]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Miaohe-Lin/close-various-race-windows-for-swap/20210408-211224
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 5e46d1b78a03d52306f21f77a4e4a144b6d31486
config: x86_64-randconfig-a012-20210408 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 56ea2e2fdd691136d5e6631fa0e447173694b82c)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/56e65e21c8c9858e36c3bca84006a15fe9b85efd
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Miaohe-Lin/close-various-race-windows-for-swap/20210408-211224
git checkout 56e65e21c8c9858e36c3bca84006a15fe9b85efd
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>):
>> mm/memory.c:3300:7: error: implicit declaration of function 'get_swap_device' [-Werror,-Wimplicit-function-declaration]
si = get_swap_device(entry);
^
mm/memory.c:3300:7: note: did you mean 'get_cpu_device'?
include/linux/cpu.h:38:23: note: 'get_cpu_device' declared here
extern struct device *get_cpu_device(unsigned cpu);
^
>> mm/memory.c:3300:5: warning: incompatible integer to pointer conversion assigning to 'struct swap_info_struct *' from 'int' [-Wint-conversion]
si = get_swap_device(entry);
^ ~~~~~~~~~~~~~~~~~~~~~~
>> mm/memory.c:3483:3: error: implicit declaration of function 'put_swap_device' [-Werror,-Wimplicit-function-declaration]
put_swap_device(si);
^
mm/memory.c:3483:3: note: did you mean 'get_swap_device'?
mm/memory.c:3300:7: note: 'get_swap_device' declared here
si = get_swap_device(entry);
^
1 warning and 2 errors generated.
vim +/get_swap_device +3300 mm/memory.c
3258
3259 /*
3260 * We enter with non-exclusive mmap_lock (to exclude vma changes,
3261 * but allow concurrent faults), and pte mapped but not yet locked.
3262 * We return with pte unmapped and unlocked.
3263 *
3264 * We return with the mmap_lock locked or unlocked in the same cases
3265 * as does filemap_fault().
3266 */
3267 vm_fault_t do_swap_page(struct vm_fault *vmf)
3268 {
3269 struct vm_area_struct *vma = vmf->vma;
3270 struct page *page = NULL, *swapcache;
3271 struct swap_info_struct *si = NULL;
3272 swp_entry_t entry;
3273 pte_t pte;
3274 int locked;
3275 int exclusive = 0;
3276 vm_fault_t ret = 0;
3277 void *shadow = NULL;
3278
3279 if (!pte_unmap_same(vma->vm_mm, vmf->pmd, vmf->pte, vmf->orig_pte))
3280 goto out;
3281
3282 entry = pte_to_swp_entry(vmf->orig_pte);
3283 if (unlikely(non_swap_entry(entry))) {
3284 if (is_migration_entry(entry)) {
3285 migration_entry_wait(vma->vm_mm, vmf->pmd,
3286 vmf->address);
3287 } else if (is_device_private_entry(entry)) {
3288 vmf->page = device_private_entry_to_page(entry);
3289 ret = vmf->page->pgmap->ops->migrate_to_ram(vmf);
3290 } else if (is_hwpoison_entry(entry)) {
3291 ret = VM_FAULT_HWPOISON;
3292 } else {
3293 print_bad_pte(vma, vmf->address, vmf->orig_pte, NULL);
3294 ret = VM_FAULT_SIGBUS;
3295 }
3296 goto out;
3297 }
3298
3299
> 3300 si = get_swap_device(entry);
3301 /* In case we raced with swapoff. */
3302 if (unlikely(!si))
3303 goto out;
3304
3305 delayacct_set_flag(DELAYACCT_PF_SWAPIN);
3306 page = lookup_swap_cache(entry, vma, vmf->address);
3307 swapcache = page;
3308
3309 if (!page) {
3310 struct swap_info_struct *si = swp_swap_info(entry);
3311
3312 if (data_race(si->flags & SWP_SYNCHRONOUS_IO) &&
3313 __swap_count(entry) == 1) {
3314 /* skip swapcache */
3315 page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma,
3316 vmf->address);
3317 if (page) {
3318 int err;
3319
3320 __SetPageLocked(page);
3321 __SetPageSwapBacked(page);
3322 set_page_private(page, entry.val);
3323
3324 /* Tell memcg to use swap ownership records */
3325 SetPageSwapCache(page);
3326 err = mem_cgroup_charge(page, vma->vm_mm,
3327 GFP_KERNEL);
3328 ClearPageSwapCache(page);
3329 if (err) {
3330 ret = VM_FAULT_OOM;
3331 goto out_page;
3332 }
3333
3334 shadow = get_shadow_from_swap_cache(entry);
3335 if (shadow)
3336 workingset_refault(page, shadow);
3337
3338 lru_cache_add(page);
3339 swap_readpage(page, true);
3340 }
3341 } else {
3342 page = swapin_readahead(entry, GFP_HIGHUSER_MOVABLE,
3343 vmf);
3344 swapcache = page;
3345 }
3346
3347 if (!page) {
3348 /*
3349 * Back out if somebody else faulted in this pte
3350 * while we released the pte lock.
3351 */
3352 vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
3353 vmf->address, &vmf->ptl);
3354 if (likely(pte_same(*vmf->pte, vmf->orig_pte)))
3355 ret = VM_FAULT_OOM;
3356 delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
3357 goto unlock;
3358 }
3359
3360 /* Had to read the page from swap area: Major fault */
3361 ret = VM_FAULT_MAJOR;
3362 count_vm_event(PGMAJFAULT);
3363 count_memcg_event_mm(vma->vm_mm, PGMAJFAULT);
3364 } else if (PageHWPoison(page)) {
3365 /*
3366 * hwpoisoned dirty swapcache pages are kept for killing
3367 * owner processes (which may be unknown at hwpoison time)
3368 */
3369 ret = VM_FAULT_HWPOISON;
3370 delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
3371 goto out_release;
3372 }
3373
3374 locked = lock_page_or_retry(page, vma->vm_mm, vmf->flags);
3375
3376 delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
3377 if (!locked) {
3378 ret |= VM_FAULT_RETRY;
3379 goto out_release;
3380 }
3381
3382 /*
3383 * Make sure try_to_free_swap or reuse_swap_page or swapoff did not
3384 * release the swapcache from under us. The page pin, and pte_same
3385 * test below, are not enough to exclude that. Even if it is still
3386 * swapcache, we need to check that the page's swap has not changed.
3387 */
3388 if (unlikely((!PageSwapCache(page) ||
3389 page_private(page) != entry.val)) && swapcache)
3390 goto out_page;
3391
3392 page = ksm_might_need_to_copy(page, vma, vmf->address);
3393 if (unlikely(!page)) {
3394 ret = VM_FAULT_OOM;
3395 page = swapcache;
3396 goto out_page;
3397 }
3398
3399 cgroup_throttle_swaprate(page, GFP_KERNEL);
3400
3401 /*
3402 * Back out if somebody else already faulted in this pte.
3403 */
3404 vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd, vmf->address,
3405 &vmf->ptl);
3406 if (unlikely(!pte_same(*vmf->pte, vmf->orig_pte)))
3407 goto out_nomap;
3408
3409 if (unlikely(!PageUptodate(page))) {
3410 ret = VM_FAULT_SIGBUS;
3411 goto out_nomap;
3412 }
3413
3414 /*
3415 * The page isn't present yet, go ahead with the fault.
3416 *
3417 * Be careful about the sequence of operations here.
3418 * To get its accounting right, reuse_swap_page() must be called
3419 * while the page is counted on swap but not yet in mapcount i.e.
3420 * before page_add_anon_rmap() and swap_free(); try_to_free_swap()
3421 * must be called after the swap_free(), or it will never succeed.
3422 */
3423
3424 inc_mm_counter_fast(vma->vm_mm, MM_ANONPAGES);
3425 dec_mm_counter_fast(vma->vm_mm, MM_SWAPENTS);
3426 pte = mk_pte(page, vma->vm_page_prot);
3427 if ((vmf->flags & FAULT_FLAG_WRITE) && reuse_swap_page(page, NULL)) {
3428 pte = maybe_mkwrite(pte_mkdirty(pte), vma);
3429 vmf->flags &= ~FAULT_FLAG_WRITE;
3430 ret |= VM_FAULT_WRITE;
3431 exclusive = RMAP_EXCLUSIVE;
3432 }
3433 flush_icache_page(vma, page);
3434 if (pte_swp_soft_dirty(vmf->orig_pte))
3435 pte = pte_mksoft_dirty(pte);
3436 if (pte_swp_uffd_wp(vmf->orig_pte)) {
3437 pte = pte_mkuffd_wp(pte);
3438 pte = pte_wrprotect(pte);
3439 }
3440 set_pte_at(vma->vm_mm, vmf->address, vmf->pte, pte);
3441 arch_do_swap_page(vma->vm_mm, vma, vmf->address, pte, vmf->orig_pte);
3442 vmf->orig_pte = pte;
3443
3444 /* ksm created a completely new copy */
3445 if (unlikely(page != swapcache && swapcache)) {
3446 page_add_new_anon_rmap(page, vma, vmf->address, false);
3447 lru_cache_add_inactive_or_unevictable(page, vma);
3448 } else {
3449 do_page_add_anon_rmap(page, vma, vmf->address, exclusive);
3450 }
3451
3452 swap_free(entry);
3453 if (mem_cgroup_swap_full(page) ||
3454 (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
3455 try_to_free_swap(page);
3456 unlock_page(page);
3457 if (page != swapcache && swapcache) {
3458 /*
3459 * Hold the lock to avoid the swap entry to be reused
3460 * until we take the PT lock for the pte_same() check
3461 * (to avoid false positives from pte_same). For
3462 * further safety release the lock after the swap_free
3463 * so that the swap count won't change under a
3464 * parallel locked swapcache.
3465 */
3466 unlock_page(swapcache);
3467 put_page(swapcache);
3468 }
3469
3470 if (vmf->flags & FAULT_FLAG_WRITE) {
3471 ret |= do_wp_page(vmf);
3472 if (ret & VM_FAULT_ERROR)
3473 ret &= VM_FAULT_ERROR;
3474 goto out;
3475 }
3476
3477 /* No need to invalidate - it was non-present before */
3478 update_mmu_cache(vma, vmf->address, vmf->pte);
3479 unlock:
3480 pte_unmap_unlock(vmf->pte, vmf->ptl);
3481 out:
3482 if (si)
> 3483 put_swap_device(si);
3484 return ret;
3485 out_nomap:
3486 pte_unmap_unlock(vmf->pte, vmf->ptl);
3487 out_page:
3488 unlock_page(page);
3489 out_release:
3490 put_page(page);
3491 if (page != swapcache && swapcache) {
3492 unlock_page(swapcache);
3493 put_page(swapcache);
3494 }
3495 if (si)
3496 put_swap_device(si);
3497 return ret;
3498 }
3499
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 35830 bytes --]
next prev parent reply other threads:[~2021-04-08 21:37 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-08 13:08 [PATCH 0/5] close various race windows for swap Miaohe Lin
2021-04-08 13:08 ` [PATCH 1/5] mm/swapfile: add percpu_ref support " Miaohe Lin
2021-04-12 3:30 ` Huang, Ying
2021-04-12 3:30 ` Huang, Ying
2021-04-12 6:59 ` Miaohe Lin
2021-04-12 7:24 ` Huang, Ying
2021-04-12 7:24 ` Huang, Ying
2021-04-13 12:39 ` Miaohe Lin
2021-04-14 1:17 ` Huang, Ying
2021-04-14 1:17 ` Huang, Ying
2021-04-14 1:58 ` Miaohe Lin
2021-04-14 2:06 ` Huang, Ying
2021-04-14 2:06 ` Huang, Ying
2021-04-14 3:44 ` Dennis Zhou
2021-04-14 3:59 ` Huang, Ying
2021-04-14 3:59 ` Huang, Ying
2021-04-14 4:05 ` Dennis Zhou
2021-04-14 5:44 ` Huang, Ying
2021-04-14 5:44 ` Huang, Ying
2021-04-14 14:53 ` Dennis Zhou
2021-04-15 3:16 ` Miaohe Lin
2021-04-15 4:20 ` Dennis Zhou
2021-04-15 9:17 ` Miaohe Lin
2021-04-15 5:24 ` Huang, Ying
2021-04-15 5:24 ` Huang, Ying
2021-04-15 14:31 ` Dennis Zhou
2021-04-16 0:54 ` Huang, Ying
2021-04-16 0:54 ` Huang, Ying
2021-04-16 2:27 ` Miaohe Lin
2021-04-16 6:25 ` Huang, Ying
2021-04-16 6:25 ` Huang, Ying
2021-04-16 8:30 ` Miaohe Lin
2021-04-08 13:08 ` [PATCH 2/5] swap: fix do_swap_page() race with swapoff Miaohe Lin
2021-04-08 21:34 ` Tim Chen
2021-04-09 8:42 ` Miaohe Lin
2021-04-09 17:17 ` Tim Chen
2021-04-10 3:17 ` Miaohe Lin
2021-04-12 1:44 ` Huang, Ying
2021-04-12 1:44 ` Huang, Ying
2021-04-12 3:24 ` Miaohe Lin
2021-04-08 21:37 ` kernel test robot [this message]
2021-04-09 8:46 ` Miaohe Lin
2021-04-08 22:56 ` kernel test robot
2021-04-13 1:27 ` Huang, Ying
2021-04-13 1:27 ` Huang, Ying
2021-04-13 19:24 ` Tim Chen
2021-04-14 1:04 ` Huang, Ying
2021-04-14 1:04 ` Huang, Ying
2021-04-14 2:20 ` Miaohe Lin
2021-04-14 16:13 ` Tim Chen
2021-04-15 3:19 ` Miaohe Lin
2021-04-14 2:55 ` Miaohe Lin
2021-04-14 3:07 ` Huang, Ying
2021-04-14 3:07 ` Huang, Ying
2021-04-14 3:27 ` Miaohe Lin
2021-04-08 13:08 ` [PATCH 3/5] mm/swap_state: fix get_shadow_from_swap_cache() " Miaohe Lin
2021-04-13 1:33 ` Huang, Ying
2021-04-13 1:33 ` Huang, Ying
2021-04-14 2:42 ` Miaohe Lin
2021-04-08 13:08 ` [PATCH 4/5] mm/swap_state: fix potential faulted in race in swap_ra_info() Miaohe Lin
2021-04-09 8:50 ` Huang, Ying
2021-04-09 8:50 ` Huang, Ying
2021-04-09 9:00 ` Miaohe Lin
2021-04-12 0:55 ` Huang, Ying
2021-04-12 0:55 ` Huang, Ying
2021-04-12 3:17 ` Miaohe Lin
2021-04-08 13:08 ` [PATCH 5/5] mm/swap_state: fix swap_cluster_readahead() race with swapoff Miaohe Lin
2021-04-13 1:36 ` Huang, Ying
2021-04-13 1:36 ` Huang, Ying
2021-04-14 2:43 ` Miaohe Lin
2021-04-08 14:55 ` [PATCH 0/5] close various race windows for swap riteshh
2021-04-09 8:01 ` Miaohe Lin
2021-04-08 20:46 [PATCH 2/5] swap: fix do_swap_page() race with swapoff kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202104090509.oCjbls7L-lkp@intel.com \
--to=lkp@intel.com \
--cc=kbuild-all@lists.01.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.