[-next] mm/page_io: mark an intentional data race
diff mbox series

Message ID 20200206035654.2647-1-cai@lca.pw
State New
Headers show
Series
  • [-next] mm/page_io: mark an intentional data race
Related show

Commit Message

Qian Cai Feb. 6, 2020, 3:56 a.m. UTC
struct swap_info_struct si.flags could be accessed concurrently as
noticed by KCSAN,

 BUG: KCSAN: data-race in scan_swap_map_slots / swap_readpage

 write to 0xffff9c77b80ac400 of 8 bytes by task 91325 on cpu 16:
  scan_swap_map_slots+0x6fe/0xb50
  scan_swap_map_slots at mm/swapfile.c:887
  get_swap_pages+0x39d/0x5c0
  get_swap_page+0x377/0x524
  add_to_swap+0xe4/0x1c0
  shrink_page_list+0x1740/0x2820
  shrink_inactive_list+0x316/0x8b0
  shrink_lruvec+0x8dc/0x1380
  shrink_node+0x317/0xd80
  do_try_to_free_pages+0x1f7/0xa10
  try_to_free_pages+0x26c/0x5e0
  __alloc_pages_slowpath+0x458/0x1290
  __alloc_pages_nodemask+0x3bb/0x450
  alloc_pages_vma+0x8a/0x2c0
  do_anonymous_page+0x170/0x700
  __handle_mm_fault+0xc9f/0xd00
  handle_mm_fault+0xfc/0x2f0
  do_page_fault+0x263/0x6f9
  page_fault+0x34/0x40

 read to 0xffff9c77b80ac400 of 8 bytes by task 5422 on cpu 7:
  swap_readpage+0x204/0x6a0
  swap_readpage at mm/page_io.c:380
  read_swap_cache_async+0xa2/0xb0
  swapin_readahead+0x6a0/0x890
  do_swap_page+0x465/0xeb0
  __handle_mm_fault+0xc7a/0xd00
  handle_mm_fault+0xfc/0x2f0
  do_page_fault+0x263/0x6f9
  page_fault+0x34/0x40

 Reported by Kernel Concurrency Sanitizer on:
 CPU: 7 PID: 5422 Comm: gmain Tainted: G        W  O L 5.5.0-next-20200204+ #6
 Hardware name: HPE ProLiant DL385 Gen10/ProLiant DL385 Gen10, BIOS A40 07/10/2019

The write is under &si->lock, but the read is done as lockless. Since
the read only check for a specific bit in the flag, it is harmless even
if load tearing happens. Thus, just mark it as an intentional data race
using the data_race() macro.

Signed-off-by: Qian Cai <cai@lca.pw>
---
 mm/page_io.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Qian Cai Feb. 6, 2020, 8:31 p.m. UTC | #1
Please disregard this patch. I found more data races in this file, so will send a new
patch to have them at once.

> On Feb 5, 2020, at 10:56 PM, Qian Cai <cai@lca.pw> wrote:
> 
> struct swap_info_struct si.flags could be accessed concurrently as
> noticed by KCSAN,
> 
> BUG: KCSAN: data-race in scan_swap_map_slots / swap_readpage
> 
> write to 0xffff9c77b80ac400 of 8 bytes by task 91325 on cpu 16:
>  scan_swap_map_slots+0x6fe/0xb50
>  scan_swap_map_slots at mm/swapfile.c:887
>  get_swap_pages+0x39d/0x5c0
>  get_swap_page+0x377/0x524
>  add_to_swap+0xe4/0x1c0
>  shrink_page_list+0x1740/0x2820
>  shrink_inactive_list+0x316/0x8b0
>  shrink_lruvec+0x8dc/0x1380
>  shrink_node+0x317/0xd80
>  do_try_to_free_pages+0x1f7/0xa10
>  try_to_free_pages+0x26c/0x5e0
>  __alloc_pages_slowpath+0x458/0x1290
>  __alloc_pages_nodemask+0x3bb/0x450
>  alloc_pages_vma+0x8a/0x2c0
>  do_anonymous_page+0x170/0x700
>  __handle_mm_fault+0xc9f/0xd00
>  handle_mm_fault+0xfc/0x2f0
>  do_page_fault+0x263/0x6f9
>  page_fault+0x34/0x40
> 
> read to 0xffff9c77b80ac400 of 8 bytes by task 5422 on cpu 7:
>  swap_readpage+0x204/0x6a0
>  swap_readpage at mm/page_io.c:380
>  read_swap_cache_async+0xa2/0xb0
>  swapin_readahead+0x6a0/0x890
>  do_swap_page+0x465/0xeb0
>  __handle_mm_fault+0xc7a/0xd00
>  handle_mm_fault+0xfc/0x2f0
>  do_page_fault+0x263/0x6f9
>  page_fault+0x34/0x40
> 
> Reported by Kernel Concurrency Sanitizer on:
> CPU: 7 PID: 5422 Comm: gmain Tainted: G        W  O L 5.5.0-next-20200204+ #6
> Hardware name: HPE ProLiant DL385 Gen10/ProLiant DL385 Gen10, BIOS A40 07/10/2019
> 
> The write is under &si->lock, but the read is done as lockless. Since
> the read only check for a specific bit in the flag, it is harmless even
> if load tearing happens. Thus, just mark it as an intentional data race
> using the data_race() macro.
> 
> Signed-off-by: Qian Cai <cai@lca.pw>
> ---
> mm/page_io.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/page_io.c b/mm/page_io.c
> index 76965be1d40e..e33925b9178c 100644
> --- a/mm/page_io.c
> +++ b/mm/page_io.c
> @@ -377,7 +377,7 @@ int swap_readpage(struct page *page, bool synchronous)
> 		goto out;
> 	}
> 
> -	if (sis->flags & SWP_FS) {
> +	if (data_race(sis->flags & SWP_FS)) {
> 		struct file *swap_file = sis->swap_file;
> 		struct address_space *mapping = swap_file->f_mapping;
> 
> -- 
> 2.21.0 (Apple Git-122.2)
>

Patch
diff mbox series

diff --git a/mm/page_io.c b/mm/page_io.c
index 76965be1d40e..e33925b9178c 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -377,7 +377,7 @@  int swap_readpage(struct page *page, bool synchronous)
 		goto out;
 	}
 
-	if (sis->flags & SWP_FS) {
+	if (data_race(sis->flags & SWP_FS)) {
 		struct file *swap_file = sis->swap_file;
 		struct address_space *mapping = swap_file->f_mapping;