Linux s390 Architecture development
 help / color / mirror / Atom feed
* [PATCH] KVM: s390: Fix to clear PTE when discarding a swapped page
@ 2025-09-24 12:17 Gautam Gala
  2025-09-24 12:22 ` David Hildenbrand
  2025-09-27 17:14 ` kernel test robot
  0 siblings, 2 replies; 4+ messages in thread
From: Gautam Gala @ 2025-09-24 12:17 UTC (permalink / raw)
  To: Alexander Gordeev, Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, Janosch Frank,
	Claudio Imbrenda, David Hildenbrand
  Cc: linux-s390, linux-kernel, kvm

KVM run fails when guests with 'cmm' cpu feature and host are
under memory pressure and use swap heavily. This is because
npages becomes ENOMEN (out of memory) in hva_to_pfn_slow()
which inturn propagates as EFAULT to qemu. Clearing the page
table entry when discarding an address that maps to a swap
entry resolves the issue.

Suggested-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Gautam Gala <ggala@linux.ibm.com>
---
 arch/s390/include/asm/pgtable.h | 22 ++++++++++++++++++++++
 arch/s390/mm/gmap_helpers.c     | 12 +++++++++++-
 arch/s390/mm/pgtable.c          | 23 +----------------------
 3 files changed, 34 insertions(+), 23 deletions(-)

diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index c1a7a92f0575..b7100c6a4054 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -2055,4 +2055,26 @@ static inline unsigned long gmap_pgste_get_pgt_addr(unsigned long *pgt)
 	return res;
 }
 
+static inline pgste_t pgste_get_lock(pte_t *ptep)
+{
+	unsigned long value = 0;
+#ifdef CONFIG_PGSTE
+	unsigned long *ptr = (unsigned long *)(ptep + PTRS_PER_PTE);
+
+	do {
+		value = __atomic64_or_barrier(PGSTE_PCL_BIT, ptr);
+	} while (value & PGSTE_PCL_BIT);
+	value |= PGSTE_PCL_BIT;
+#endif
+	return __pgste(value);
+}
+
+static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
+{
+#ifdef CONFIG_PGSTE
+	barrier();
+	WRITE_ONCE(*(unsigned long *)(ptep + PTRS_PER_PTE), pgste_val(pgste) & ~PGSTE_PCL_BIT);
+#endif
+}
+
 #endif /* _S390_PAGE_H */
diff --git a/arch/s390/mm/gmap_helpers.c b/arch/s390/mm/gmap_helpers.c
index b63f427e7289..d4c3c36855e2 100644
--- a/arch/s390/mm/gmap_helpers.c
+++ b/arch/s390/mm/gmap_helpers.c
@@ -15,6 +15,7 @@
 #include <linux/pagewalk.h>
 #include <linux/ksm.h>
 #include <asm/gmap_helpers.h>
+#include <asm/pgtable.h>
 
 /**
  * ptep_zap_swap_entry() - discard a swap entry.
@@ -47,6 +48,7 @@ void gmap_helper_zap_one_page(struct mm_struct *mm, unsigned long vmaddr)
 {
 	struct vm_area_struct *vma;
 	spinlock_t *ptl;
+	pgste_t pgste;
 	pte_t *ptep;
 
 	mmap_assert_locked(mm);
@@ -60,8 +62,16 @@ void gmap_helper_zap_one_page(struct mm_struct *mm, unsigned long vmaddr)
 	ptep = get_locked_pte(mm, vmaddr, &ptl);
 	if (unlikely(!ptep))
 		return;
-	if (pte_swap(*ptep))
+	if (pte_swap(*ptep)) {
+		preempt_disable();
+		pgste = pgste_get_lock(ptep);
+
 		ptep_zap_swap_entry(mm, pte_to_swp_entry(*ptep));
+		pte_clear(mm, vmaddr, ptep);
+
+		pgste_set_unlock(ptep, pgste);
+		preempt_enable();
+	}
 	pte_unmap_unlock(ptep, ptl);
 }
 EXPORT_SYMBOL_GPL(gmap_helper_zap_one_page);
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 60688be4e876..879f39366e6c 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -24,6 +24,7 @@
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
 #include <asm/page-states.h>
+#include <asm/pgtable.h>
 #include <asm/machine.h>
 
 pgprot_t pgprot_writecombine(pgprot_t prot)
@@ -115,28 +116,6 @@ static inline pte_t ptep_flush_lazy(struct mm_struct *mm,
 	return old;
 }
 
-static inline pgste_t pgste_get_lock(pte_t *ptep)
-{
-	unsigned long value = 0;
-#ifdef CONFIG_PGSTE
-	unsigned long *ptr = (unsigned long *)(ptep + PTRS_PER_PTE);
-
-	do {
-		value = __atomic64_or_barrier(PGSTE_PCL_BIT, ptr);
-	} while (value & PGSTE_PCL_BIT);
-	value |= PGSTE_PCL_BIT;
-#endif
-	return __pgste(value);
-}
-
-static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
-{
-#ifdef CONFIG_PGSTE
-	barrier();
-	WRITE_ONCE(*(unsigned long *)(ptep + PTRS_PER_PTE), pgste_val(pgste) & ~PGSTE_PCL_BIT);
-#endif
-}
-
 static inline pgste_t pgste_get(pte_t *ptep)
 {
 	unsigned long pgste = 0;
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: s390: Fix to clear PTE when discarding a swapped page
  2025-09-24 12:17 [PATCH] KVM: s390: Fix to clear PTE when discarding a swapped page Gautam Gala
@ 2025-09-24 12:22 ` David Hildenbrand
  2025-09-24 12:31   ` Claudio Imbrenda
  2025-09-27 17:14 ` kernel test robot
  1 sibling, 1 reply; 4+ messages in thread
From: David Hildenbrand @ 2025-09-24 12:22 UTC (permalink / raw)
  To: Gautam Gala, Alexander Gordeev, Gerald Schaefer, Heiko Carstens,
	Vasily Gorbik, Christian Borntraeger, Sven Schnelle,
	Janosch Frank, Claudio Imbrenda
  Cc: linux-s390, linux-kernel, kvm

On 24.09.25 14:17, Gautam Gala wrote:
> KVM run fails when guests with 'cmm' cpu feature and host are
> under memory pressure and use swap heavily. This is because
> npages becomes ENOMEN (out of memory) in hva_to_pfn_slow()
> which inturn propagates as EFAULT to qemu. Clearing the page
> table entry when discarding an address that maps to a swap
> entry resolves the issue.
> 
> Suggested-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
> Signed-off-by: Gautam Gala <ggala@linux.ibm.com>
> ---

Sounds bad,

I assume we want Fixes: and CC: stable, right?

-- 
Cheers

David / dhildenb


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: s390: Fix to clear PTE when discarding a swapped page
  2025-09-24 12:22 ` David Hildenbrand
@ 2025-09-24 12:31   ` Claudio Imbrenda
  0 siblings, 0 replies; 4+ messages in thread
From: Claudio Imbrenda @ 2025-09-24 12:31 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Gautam Gala, Alexander Gordeev, Gerald Schaefer, Heiko Carstens,
	Vasily Gorbik, Christian Borntraeger, Sven Schnelle,
	Janosch Frank, linux-s390, linux-kernel, kvm

On Wed, 24 Sep 2025 14:22:05 +0200
David Hildenbrand <david@redhat.com> wrote:

> On 24.09.25 14:17, Gautam Gala wrote:
> > KVM run fails when guests with 'cmm' cpu feature and host are
> > under memory pressure and use swap heavily. This is because
> > npages becomes ENOMEN (out of memory) in hva_to_pfn_slow()
> > which inturn propagates as EFAULT to qemu. Clearing the page
> > table entry when discarding an address that maps to a swap
> > entry resolves the issue.
> > 
> > Suggested-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
> > Signed-off-by: Gautam Gala <ggala@linux.ibm.com>
> > ---  
> 
> Sounds bad,
> 
> I assume we want Fixes: and CC: stable, right?

yes; I'll add those when picking up

Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: s390: Fix to clear PTE when discarding a swapped page
  2025-09-24 12:17 [PATCH] KVM: s390: Fix to clear PTE when discarding a swapped page Gautam Gala
  2025-09-24 12:22 ` David Hildenbrand
@ 2025-09-27 17:14 ` kernel test robot
  1 sibling, 0 replies; 4+ messages in thread
From: kernel test robot @ 2025-09-27 17:14 UTC (permalink / raw)
  To: Gautam Gala, Alexander Gordeev, Gerald Schaefer, Heiko Carstens,
	Vasily Gorbik, Christian Borntraeger, Sven Schnelle,
	Janosch Frank, Claudio Imbrenda, David Hildenbrand
  Cc: llvm, oe-kbuild-all, linux-s390, linux-kernel, kvm

Hi Gautam,

kernel test robot noticed the following build warnings:

[auto build test WARNING on s390/features]
[also build test WARNING on linus/master v6.17-rc7 next-20250926]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Gautam-Gala/KVM-s390-Fix-to-clear-PTE-when-discarding-a-swapped-page/20250924-201847
base:   https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git features
patch link:    https://lore.kernel.org/r/20250924121707.145350-1-ggala%40linux.ibm.com
patch subject: [PATCH] KVM: s390: Fix to clear PTE when discarding a swapped page
config: s390-defconfig (https://download.01.org/0day-ci/archive/20250928/202509280003.NWFBhwme-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project cafc064fc7a96b3979a023ddae1da2b499d6c954)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250928/202509280003.NWFBhwme-lkp@intel.com/reproduce)

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 <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509280003.NWFBhwme-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from arch/s390/boot/als.c:9:
   In file included from arch/s390/include/asm/sclp.h:26:
   In file included from arch/s390/include/asm/chpid.h:10:
   In file included from arch/s390/include/asm/cio.h:10:
   In file included from arch/s390/include/asm/dma-types.h:7:
   In file included from include/linux/io.h:12:
   In file included from arch/s390/include/asm/io.h:15:
>> arch/s390/include/asm/pgtable.h:2065:48: warning: passing 'unsigned long *' to parameter of type 'long *' converts between pointers to integer types with different sign [-Wpointer-sign]
    2065 |                 value = __atomic64_or_barrier(PGSTE_PCL_BIT, ptr);
         |                                                              ^~~
   arch/s390/include/asm/atomic_ops.h:161:1: note: passing argument to parameter 'ptr' here
     161 | __ATOMIC64_OPS(__atomic64_or,  "ogr")
         | ^
   arch/s390/include/asm/atomic_ops.h:157:2: note: expanded from macro '__ATOMIC64_OPS'
     157 |         __ATOMIC64_OP(op_name##_barrier, op_string)
         |         ^
   arch/s390/include/asm/atomic_ops.h:141:53: note: expanded from macro '__ATOMIC64_OP'
     141 | static __always_inline long op_name(long val, long *ptr)                \
         |                                                     ^
   1 warning generated.


vim +2065 arch/s390/include/asm/pgtable.h

  2057	
  2058	static inline pgste_t pgste_get_lock(pte_t *ptep)
  2059	{
  2060		unsigned long value = 0;
  2061	#ifdef CONFIG_PGSTE
  2062		unsigned long *ptr = (unsigned long *)(ptep + PTRS_PER_PTE);
  2063	
  2064		do {
> 2065			value = __atomic64_or_barrier(PGSTE_PCL_BIT, ptr);
  2066		} while (value & PGSTE_PCL_BIT);
  2067		value |= PGSTE_PCL_BIT;
  2068	#endif
  2069		return __pgste(value);
  2070	}
  2071	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-09-27 17:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-24 12:17 [PATCH] KVM: s390: Fix to clear PTE when discarding a swapped page Gautam Gala
2025-09-24 12:22 ` David Hildenbrand
2025-09-24 12:31   ` Claudio Imbrenda
2025-09-27 17:14 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox