diff mbox series

[4/5] mm: Add PageAnonNotKsm()

Message ID 20241002152533.1350629-5-willy@infradead.org (mailing list archive)
State New
Headers show
Series Remove PageKsm() | expand

Commit Message

Matthew Wilcox Oct. 2, 2024, 3:25 p.m. UTC
Check that this anonymous page is really anonymous, not
anonymous-or-KSM.  This optimises the debug check, but its real purpose
is to remove the last two users of PageKsm().

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 include/linux/page-flags.h | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

Comments

Marek Szyprowski Oct. 4, 2024, 11:46 a.m. UTC | #1
On 02.10.2024 17:25, Matthew Wilcox (Oracle) wrote:
> Check that this anonymous page is really anonymous, not
> anonymous-or-KSM.  This optimises the debug check, but its real purpose
> is to remove the last two users of PageKsm().
>
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
>   include/linux/page-flags.h | 11 +++++++++--
>   1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
> index 4c2dfe289046..157c4ffc2fdc 100644
> --- a/include/linux/page-flags.h
> +++ b/include/linux/page-flags.h
> @@ -689,6 +689,13 @@ static __always_inline bool folio_test_anon(const struct folio *folio)
>   	return ((unsigned long)folio->mapping & PAGE_MAPPING_ANON) != 0;
>   }
>   
> +static __always_inline bool PageAnonNotKsm(const struct page *page)
> +{
> +	unsigned long flags = (unsigned long)page_folio(page)->mapping;
> +
> +	return (flags & PAGE_MAPPING_FLAGS) == PAGE_MAPPING_ANON;
> +}
> +
>   static __always_inline bool PageAnon(const struct page *page)
>   {
>   	return folio_test_anon(page_folio(page));
> @@ -1129,14 +1136,14 @@ static __always_inline int PageAnonExclusive(const struct page *page)
>   
>   static __always_inline void SetPageAnonExclusive(struct page *page)
>   {
> -	VM_BUG_ON_PGFLAGS(!PageAnon(page) || PageKsm(page), page);
> +	VM_BUG_ON_PGFLAGS(PageAnonNotKsm(page), page);

!PageAnonNotKsm(page) ?

At least such change fixes booting of today's linux-next with debug 
enabled on RISC-V based boards.


>   	VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page);
>   	set_bit(PG_anon_exclusive, &PF_ANY(page, 1)->flags);
>   }
>   
>   static __always_inline void ClearPageAnonExclusive(struct page *page)
>   {
> -	VM_BUG_ON_PGFLAGS(!PageAnon(page) || PageKsm(page), page);
> +	VM_BUG_ON_PGFLAGS(PageAnonNotKsm(page), page);

ditto


>   	VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page);
>   	clear_bit(PG_anon_exclusive, &PF_ANY(page, 1)->flags);
>   }

Best regards
kernel test robot Oct. 6, 2024, 2:11 p.m. UTC | #2
Hello,

kernel test robot noticed "kernel_BUG_at_include/linux/page-flags.h" on:

commit: 3e721b4c4250773f06818e43821a30108775a59b ("[PATCH 4/5] mm: Add PageAnonNotKsm()")
url: https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/ksm-Use-a-folio-in-try_to_merge_one_page/20241002-232657
base: https://git.kernel.org/cgit/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/all/20241002152533.1350629-5-willy@infradead.org/
patch subject: [PATCH 4/5] mm: Add PageAnonNotKsm()

in testcase: boot

compiler: clang-18
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+------------------------------------------+------------+------------+
|                                          | 3e3e3b90a7 | 3e721b4c42 |
+------------------------------------------+------------+------------+
| boot_successes                           | 6          | 0          |
| boot_failures                            | 0          | 6          |
| kernel_BUG_at_include/linux/page-flags.h | 0          | 6          |
| Oops:invalid_opcode:#[##]SMP             | 0          | 6          |
| RIP:folio_add_new_anon_rmap              | 0          | 6          |
| Kernel_panic-not_syncing:Fatal_exception | 0          | 6          |
+------------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202410062122.193c5b0e-oliver.sang@intel.com


[  219.772371][   T65] ------------[ cut here ]------------
[  219.783937][   T65] kernel BUG at include/linux/page-flags.h:1139!
[  219.798558][   T65] Oops: invalid opcode: 0000 [#1] SMP
[  219.800949][   T65] CPU: 1 UID: 0 PID: 65 Comm: kworker/u10:1 Tainted: G                T  6.12.0-rc1-00097-g3e721b4c4250 #1
[  219.800949][   T65] Tainted: [T]=RANDSTRUCT
[ 219.800949][ T65] RIP: 0010:folio_add_new_anon_rmap (include/linux/page-flags.h:1139) 
[ 219.800949][ T65] Code: 40 ec ff 48 89 df 48 c7 c6 1a 3c 7b 90 e8 78 58 fc ff 90 0f 0b e8 40 d9 e7 ff 4c 89 ff 48 c7 c6 ef 26 78 90 e8 61 58 fc ff 90 <0f> 0b e8 29 d9 e7 ff 4c 89 ff 48 c7 c6 d9 61 68 90 e8 4a 58 fc ff
All code
========
   0:	40 ec                	rex in (%dx),%al
   2:	ff 48 89             	decl   -0x77(%rax)
   5:	df 48 c7             	fisttps -0x39(%rax)
   8:	c6                   	(bad)
   9:	1a 3c 7b             	sbb    (%rbx,%rdi,2),%bh
   c:	90                   	nop
   d:	e8 78 58 fc ff       	call   0xfffffffffffc588a
  12:	90                   	nop
  13:	0f 0b                	ud2
  15:	e8 40 d9 e7 ff       	call   0xffffffffffe7d95a
  1a:	4c 89 ff             	mov    %r15,%rdi
  1d:	48 c7 c6 ef 26 78 90 	mov    $0xffffffff907826ef,%rsi
  24:	e8 61 58 fc ff       	call   0xfffffffffffc588a
  29:	90                   	nop
  2a:*	0f 0b                	ud2		<-- trapping instruction
  2c:	e8 29 d9 e7 ff       	call   0xffffffffffe7d95a
  31:	4c 89 ff             	mov    %r15,%rdi
  34:	48 c7 c6 d9 61 68 90 	mov    $0xffffffff906861d9,%rsi
  3b:	e8 4a 58 fc ff       	call   0xfffffffffffc588a

Code starting with the faulting instruction
===========================================
   0:	0f 0b                	ud2
   2:	e8 29 d9 e7 ff       	call   0xffffffffffe7d930
   7:	4c 89 ff             	mov    %r15,%rdi
   a:	48 c7 c6 d9 61 68 90 	mov    $0xffffffff906861d9,%rsi
  11:	e8 4a 58 fc ff       	call   0xfffffffffffc5860
[  219.800949][   T65] RSP: 0000:ffff90094044fae8 EFLAGS: 00010246
[  219.800949][   T65] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000
[  219.800949][   T65] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[  219.800949][   T65] RBP: ffff90094044fb28 R08: 0000000000000000 R09: 0000000000000000
[  219.800949][   T65] R10: 0000000000000000 R11: 0000000000000000 R12: ffff900940107000
[  219.800949][   T65] R13: 00000007fffffffe R14: 0000000000000000 R15: fffff9dd10bf0ec0
[  219.800949][   T65] FS:  0000000000000000(0000) GS:ffff900c2fd00000(0000) knlGS:0000000000000000
[  219.800949][   T65] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  219.800949][   T65] CR2: 0000000000000000 CR3: 00000000a1a37000 CR4: 00000000000006b0
[  219.800949][   T65] Call Trace:
[  219.800949][   T65]  <TASK>
[ 219.800949][ T65] ? __die_body (arch/x86/kernel/dumpstack.c:421) 
[ 219.800949][ T65] ? die (arch/x86/kernel/dumpstack.c:?) 
[ 219.800949][ T65] ? do_trap (arch/x86/kernel/traps.c:171 arch/x86/kernel/traps.c:197) 
[ 219.800949][ T65] ? do_error_trap (arch/x86/kernel/traps.c:217) 
[ 219.800949][ T65] ? folio_add_new_anon_rmap (include/linux/page-flags.h:1139) 
[ 219.800949][ T65] ? handle_invalid_op (arch/x86/kernel/traps.c:254) 
[ 219.800949][ T65] ? folio_add_new_anon_rmap (include/linux/page-flags.h:1139) 
[ 219.800949][ T65] ? exc_invalid_op (arch/x86/kernel/traps.c:315) 
[ 219.800949][ T65] ? asm_exc_invalid_op (arch/x86/include/asm/idtentry.h:621) 
[ 219.800949][ T65] ? folio_add_new_anon_rmap (include/linux/page-flags.h:1139) 
[ 219.800949][ T65] ? folio_add_new_anon_rmap (include/linux/page-flags.h:1139) 
[ 219.800949][ T65] handle_pte_fault (mm/memory.c:4842) 
[ 219.800949][ T65] ? ftrace_likely_update (kernel/trace/trace_branch.c:?) 
[ 219.800949][ T65] handle_mm_fault (mm/memory.c:?) 
[ 219.800949][ T65] ? handle_mm_fault (arch/x86/include/asm/current.h:49 mm/memory.c:6062) 
[ 219.800949][ T65] __get_user_pages (mm/gup.c:1189) 
[ 219.800949][ T65] ? ftrace_likely_update (kernel/trace/trace_branch.c:?) 
[ 219.800949][ T65] ? is_valid_gup_args (mm/gup.c:2546) 
[ 219.800949][ T65] get_user_pages_remote (mm/gup.c:?) 
[ 219.800949][ T65] get_arg_page (fs/exec.c:225) 
[ 219.800949][ T65] copy_string_kernel (fs/exec.c:685) 
[ 219.800949][ T65] ? __cond_resched (kernel/sched/core.c:?) 
[ 219.800949][ T65] kernel_execve (fs/exec.c:2000) 
[ 219.800949][ T65] call_usermodehelper_exec_async (kernel/umh.c:110) 
[ 219.800949][ T65] ? __cfi_call_usermodehelper_exec_async (kernel/umh.c:65) 
[ 219.800949][ T65] ret_from_fork (arch/x86/kernel/process.c:153) 
[ 219.800949][ T65] ? __cfi_call_usermodehelper_exec_async (kernel/umh.c:65) 
[ 219.800949][ T65] ret_from_fork_asm (arch/x86/entry/entry_64.S:257) 
[  219.800949][   T65]  </TASK>
[  219.800949][   T65] Modules linked in:
[  220.299454][   T65] ---[ end trace 0000000000000000 ]---
[ 220.310211][ T65] RIP: 0010:folio_add_new_anon_rmap (include/linux/page-flags.h:1139) 
[ 220.322429][ T65] Code: 40 ec ff 48 89 df 48 c7 c6 1a 3c 7b 90 e8 78 58 fc ff 90 0f 0b e8 40 d9 e7 ff 4c 89 ff 48 c7 c6 ef 26 78 90 e8 61 58 fc ff 90 <0f> 0b e8 29 d9 e7 ff 4c 89 ff 48 c7 c6 d9 61 68 90 e8 4a 58 fc ff
All code
========
   0:	40 ec                	rex in (%dx),%al
   2:	ff 48 89             	decl   -0x77(%rax)
   5:	df 48 c7             	fisttps -0x39(%rax)
   8:	c6                   	(bad)
   9:	1a 3c 7b             	sbb    (%rbx,%rdi,2),%bh
   c:	90                   	nop
   d:	e8 78 58 fc ff       	call   0xfffffffffffc588a
  12:	90                   	nop
  13:	0f 0b                	ud2
  15:	e8 40 d9 e7 ff       	call   0xffffffffffe7d95a
  1a:	4c 89 ff             	mov    %r15,%rdi
  1d:	48 c7 c6 ef 26 78 90 	mov    $0xffffffff907826ef,%rsi
  24:	e8 61 58 fc ff       	call   0xfffffffffffc588a
  29:	90                   	nop
  2a:*	0f 0b                	ud2		<-- trapping instruction
  2c:	e8 29 d9 e7 ff       	call   0xffffffffffe7d95a
  31:	4c 89 ff             	mov    %r15,%rdi
  34:	48 c7 c6 d9 61 68 90 	mov    $0xffffffff906861d9,%rsi
  3b:	e8 4a 58 fc ff       	call   0xfffffffffffc588a

Code starting with the faulting instruction
===========================================
   0:	0f 0b                	ud2
   2:	e8 29 d9 e7 ff       	call   0xffffffffffe7d930
   7:	4c 89 ff             	mov    %r15,%rdi
   a:	48 c7 c6 d9 61 68 90 	mov    $0xffffffff906861d9,%rsi
  11:	e8 4a 58 fc ff       	call   0xfffffffffffc5860


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20241006/202410062122.193c5b0e-oliver.sang@intel.com
David Hildenbrand Oct. 7, 2024, 9:46 a.m. UTC | #3
On 02.10.24 17:25, Matthew Wilcox (Oracle) wrote:
> Check that this anonymous page is really anonymous, not
> anonymous-or-KSM.  This optimises the debug check, but its real purpose
> is to remove the last two users of PageKsm().
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
>   include/linux/page-flags.h | 11 +++++++++--
>   1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
> index 4c2dfe289046..157c4ffc2fdc 100644
> --- a/include/linux/page-flags.h
> +++ b/include/linux/page-flags.h
> @@ -689,6 +689,13 @@ static __always_inline bool folio_test_anon(const struct folio *folio)
>   	return ((unsigned long)folio->mapping & PAGE_MAPPING_ANON) != 0;
>   }
>   
> +static __always_inline bool PageAnonNotKsm(const struct page *page)
> +{
> +	unsigned long flags = (unsigned long)page_folio(page)->mapping;
> +
> +	return (flags & PAGE_MAPPING_FLAGS) == PAGE_MAPPING_ANON;
> +}
> +
>   static __always_inline bool PageAnon(const struct page *page)
>   {
>   	return folio_test_anon(page_folio(page));
> @@ -1129,14 +1136,14 @@ static __always_inline int PageAnonExclusive(const struct page *page)
>   
>   static __always_inline void SetPageAnonExclusive(struct page *page)
>   {
> -	VM_BUG_ON_PGFLAGS(!PageAnon(page) || PageKsm(page), page);
> +	VM_BUG_ON_PGFLAGS(PageAnonNotKsm(page), page);
>   	VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page);
>   	set_bit(PG_anon_exclusive, &PF_ANY(page, 1)->flags);
>   }
>   
>   static __always_inline void ClearPageAnonExclusive(struct page *page)
>   {
> -	VM_BUG_ON_PGFLAGS(!PageAnon(page) || PageKsm(page), page);
> +	VM_BUG_ON_PGFLAGS(PageAnonNotKsm(page), page);
>   	VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page);
>   	clear_bit(PG_anon_exclusive, &PF_ANY(page, 1)->flags);
>   }

With the "!" added in both cases

Acked-by: David Hildenbrand <david@redhat.com>
diff mbox series

Patch

diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 4c2dfe289046..157c4ffc2fdc 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -689,6 +689,13 @@  static __always_inline bool folio_test_anon(const struct folio *folio)
 	return ((unsigned long)folio->mapping & PAGE_MAPPING_ANON) != 0;
 }
 
+static __always_inline bool PageAnonNotKsm(const struct page *page)
+{
+	unsigned long flags = (unsigned long)page_folio(page)->mapping;
+
+	return (flags & PAGE_MAPPING_FLAGS) == PAGE_MAPPING_ANON;
+}
+
 static __always_inline bool PageAnon(const struct page *page)
 {
 	return folio_test_anon(page_folio(page));
@@ -1129,14 +1136,14 @@  static __always_inline int PageAnonExclusive(const struct page *page)
 
 static __always_inline void SetPageAnonExclusive(struct page *page)
 {
-	VM_BUG_ON_PGFLAGS(!PageAnon(page) || PageKsm(page), page);
+	VM_BUG_ON_PGFLAGS(PageAnonNotKsm(page), page);
 	VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page);
 	set_bit(PG_anon_exclusive, &PF_ANY(page, 1)->flags);
 }
 
 static __always_inline void ClearPageAnonExclusive(struct page *page)
 {
-	VM_BUG_ON_PGFLAGS(!PageAnon(page) || PageKsm(page), page);
+	VM_BUG_ON_PGFLAGS(PageAnonNotKsm(page), page);
 	VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page);
 	clear_bit(PG_anon_exclusive, &PF_ANY(page, 1)->flags);
 }