diff mbox

sparc32: Fix impossibility of swap disabling after intensive swap using

Message ID 20100525.233849.104052594.davem@davemloft.net
State Accepted
Delegated to: David Miller
Headers show

Commit Message

David Miller May 26, 2010, 6:38 a.m. UTC
From: Тхай Кирилл <tkhai@yandex.ru>
Date: Fri, 30 Apr 2010 09:57:19 +0400

> I can mistake, but it seems to me, that pte_none is more wide check,
> than belonging pte to mmu device.

Not exactly.  pte_none() should be true if the PTE encodes nothing,
not a swap entry, not a MMU PTE, nothing at all.

> In other case none_mask must be something like 0xF0000004, because
> hardware ignores ptes with zeroed lower two bits.

It seems that the correct thing to do is to kill this none_mask thing
entirely.

Could you try this patch instead of your's?

Thanks!

--
sparc32: Kill none_mask, it's bogus.

For some reason, the pte_none() calculation for srmmu sparc32
chips was masking out the top 4 bits.  That doesn't make any
sense, as those are just some of the physical bits of the PTE
encoding.

Furthermore, this mistake breaks things when the offset of of a swap
entry has a large enough offset as reported by Тхай Кирилл.

Sun4c always set it to zero, so it's really completely useless,
kill it.

Reported-by: Тхай Кирилл <tkhai@yandex.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 arch/sparc/include/asm/pgtable_32.h |    5 ++---
 arch/sparc/mm/srmmu.c               |    2 --
 arch/sparc/mm/sun4c.c               |    3 ---
 3 files changed, 2 insertions(+), 8 deletions(-)

Comments

Kirill Tkhai May 27, 2010, 8:28 p.m. UTC | #1
Yes, it solves the problem.

26.05.10, 10:38, "David Miller" <davem@davemloft.net>:

> From: Тхай Кирилл 
>  Date: Fri, 30 Apr 2010 09:57:19 +0400
>  
>  > I can mistake, but it seems to me, that pte_none is more wide check,
>  > than belonging pte to mmu device.
>  
>  Not exactly.  pte_none() should be true if the PTE encodes nothing,
>  not a swap entry, not a MMU PTE, nothing at all.
>  
>  > In other case none_mask must be something like 0xF0000004, because
>  > hardware ignores ptes with zeroed lower two bits.
>  
>  It seems that the correct thing to do is to kill this none_mask thing
>  entirely.
>  
>  Could you try this patch instead of your's?
>  
>  Thanks!
>  
>  --
>  sparc32: Kill none_mask, it's bogus.
>  
>  For some reason, the pte_none() calculation for srmmu sparc32
>  chips was masking out the top 4 bits.  That doesn't make any
>  sense, as those are just some of the physical bits of the PTE
>  encoding.
>  
>  Furthermore, this mistake breaks things when the offset of of a swap
>  entry has a large enough offset as reported by Тхай Кирилл.
>  
>  Sun4c always set it to zero, so it's really completely useless,
>  kill it.
>  
>  Reported-by: Тхай Кирилл 
>  Signed-off-by: David S. Miller 
>  ---
>   arch/sparc/include/asm/pgtable_32.h |    5 ++---
>   arch/sparc/mm/srmmu.c               |    2 --
>   arch/sparc/mm/sun4c.c               |    3 ---
>   3 files changed, 2 insertions(+), 8 deletions(-)
>  
>  diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
>  index 77f906d..0ece77f 100644
>  --- a/arch/sparc/include/asm/pgtable_32.h
>  +++ b/arch/sparc/include/asm/pgtable_32.h
>  @@ -142,13 +142,12 @@ BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page_vaddr, pgd_t)
>   #define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
>   #define pgd_page_vaddr(pgd) BTFIXUP_CALL(pgd_page_vaddr)(pgd)
>   
>  -BTFIXUPDEF_SETHI(none_mask)
>   BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
>   BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
>   
>   static inline int pte_none(pte_t pte)
>   {
>  -	return !(pte_val(pte) & ~BTFIXUP_SETHI(none_mask));
>  +	return !pte_val(pte);
>   }
>   
>   #define pte_present(pte) BTFIXUP_CALL(pte_present)(pte)
>  @@ -160,7 +159,7 @@ BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
>   
>   static inline int pmd_none(pmd_t pmd)
>   {
>  -	return !(pmd_val(pmd) & ~BTFIXUP_SETHI(none_mask));
>  +	return !pmd_val(pmd);
>   }
>   
>   #define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd)
>  diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
>  index f5f75a5..b0b43aa 100644
>  --- a/arch/sparc/mm/srmmu.c
>  +++ b/arch/sparc/mm/srmmu.c
>  @@ -2215,8 +2215,6 @@ void __init ld_mmu_srmmu(void)
>   	BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM);
>   	BTFIXUPSET_CALL(pgd_page_vaddr, srmmu_pgd_page, BTFIXUPCALL_NORM);
>   
>  -	BTFIXUPSET_SETHI(none_mask, 0xF0000000);
>  -
>   	BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM);
>   	BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0);
>   
>  diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
>  index cf38846..4289f90 100644
>  --- a/arch/sparc/mm/sun4c.c
>  +++ b/arch/sparc/mm/sun4c.c
>  @@ -2087,9 +2087,6 @@ void __init ld_mmu_sun4c(void)
>   
>   	BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0);
>   
>  -	/* The 2.4.18 code does not set this on sun4c, how does it work? XXX */
>  -	/* BTFIXUPSET_SETHI(none_mask, 0x00000000); */	/* Defaults to zero? */
>  -
>   	BTFIXUPSET_CALL(pte_pfn, sun4c_pte_pfn, BTFIXUPCALL_NORM);
>   #if 0 /* PAGE_SHIFT <= 12 */ /* Eek. Investigate. XXX */
>   	BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1));
>  
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller May 27, 2010, 8:41 p.m. UTC | #2
From: Tkhai Kirill <tkhai@yandex.ru>
Date: Fri, 28 May 2010 00:28:03 +0400

> Yes, it solves the problem.

Thanks for finding this problem and testing the final fix.
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 77f906d..0ece77f 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -142,13 +142,12 @@  BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page_vaddr, pgd_t)
 #define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
 #define pgd_page_vaddr(pgd) BTFIXUP_CALL(pgd_page_vaddr)(pgd)
 
-BTFIXUPDEF_SETHI(none_mask)
 BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
 BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
 
 static inline int pte_none(pte_t pte)
 {
-	return !(pte_val(pte) & ~BTFIXUP_SETHI(none_mask));
+	return !pte_val(pte);
 }
 
 #define pte_present(pte) BTFIXUP_CALL(pte_present)(pte)
@@ -160,7 +159,7 @@  BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
 
 static inline int pmd_none(pmd_t pmd)
 {
-	return !(pmd_val(pmd) & ~BTFIXUP_SETHI(none_mask));
+	return !pmd_val(pmd);
 }
 
 #define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd)
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index f5f75a5..b0b43aa 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -2215,8 +2215,6 @@  void __init ld_mmu_srmmu(void)
 	BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pgd_page_vaddr, srmmu_pgd_page, BTFIXUPCALL_NORM);
 
-	BTFIXUPSET_SETHI(none_mask, 0xF0000000);
-
 	BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0);
 
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index cf38846..4289f90 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -2087,9 +2087,6 @@  void __init ld_mmu_sun4c(void)
 
 	BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0);
 
-	/* The 2.4.18 code does not set this on sun4c, how does it work? XXX */
-	/* BTFIXUPSET_SETHI(none_mask, 0x00000000); */	/* Defaults to zero? */
-
 	BTFIXUPSET_CALL(pte_pfn, sun4c_pte_pfn, BTFIXUPCALL_NORM);
 #if 0 /* PAGE_SHIFT <= 12 */ /* Eek. Investigate. XXX */
 	BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1));