Skip to contentSkip to conversation

mm: Unify pte_to_pgoff and pgoff_to_pte helpers

PATCH In review Cyrill Gorcunov 4 participants 10 messages Aug 14, 2013

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 mm: Unify pte_to_pgoff and pgoff_to_pte helpers

Use unified pte_bfop helper to manipulate bits in pte/pgoff bitfield.

Cc Andrew Morton <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Pavel Emelyanov <[email protected]>
Cc Matt Mackall <[email protected]>
Cc Xiao Guangrong <[email protected]>
Cc Marcelo Tosatti <[email protected]>
Cc KOSAKI Motohiro <[email protected]>
Cc Stephen Rothwell <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc "Aneesh Kumar K.V" <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Ingo Molnar <[email protected]>
---
 arch/x86/include/asm/pgtable-2level.h |   51 ++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 24 deletions(-)
arch/x86/include/asm/pgtable-2level.h +27 -24
Index: linux-2.6.git/arch/x86/include/asm/pgtable-2level.h
===================================================================
@@ -55,8 +55,11 @@ static inline pmd_t native_pmdp_get_and_
 #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp)
 #endif
 
-#define _mfrob(v,r,m,l)		((((v) >> (r)) & (m)) << (l))
-#define __frob(v,r,l)		(((v) >> (r)) << (l))
+/*
+ * For readable bitfield manipulations.
+ */
+#define PTE_FILE_NOMASK		(-1U)
+#define pte_bfop(v,r,m,l)	((((v) >> (r)) & (m)) << (l))
 
 #ifdef CONFIG_MEM_SOFT_DIRTY
 
@@ -82,18 +85,18 @@ static inline pmd_t native_pmdp_get_and_
 #define PTE_FILE_LSHIFT3	(PTE_FILE_BITS1 + PTE_FILE_BITS2)
 #define PTE_FILE_LSHIFT4	(PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)
 
-#define pte_to_pgoff(pte)							    \
-	(_mfrob((pte).pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1, 0)		  + \
-	 _mfrob((pte).pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2, PTE_FILE_LSHIFT2) + \
-	 _mfrob((pte).pte_low, PTE_FILE_SHIFT3, PTE_FILE_MASK3, PTE_FILE_LSHIFT3) + \
-	 __frob((pte).pte_low, PTE_FILE_SHIFT4, PTE_FILE_LSHIFT4))
-
-#define pgoff_to_pte(off)							\
-	((pte_t) { .pte_low =							\
-	_mfrob(off,                0, PTE_FILE_MASK1, PTE_FILE_SHIFT1)	+	\
-	_mfrob(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2, PTE_FILE_SHIFT2)	+	\
-	_mfrob(off, PTE_FILE_LSHIFT3, PTE_FILE_MASK3, PTE_FILE_SHIFT3)	+	\
-	__frob(off, PTE_FILE_LSHIFT4, PTE_FILE_SHIFT4)			+	\
+#define pte_to_pgoff(pte)								  \
+	(pte_bfop((pte).pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1, 0)			+ \
+	 pte_bfop((pte).pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2, PTE_FILE_LSHIFT2)	+ \
+	 pte_bfop((pte).pte_low, PTE_FILE_SHIFT3, PTE_FILE_MASK3, PTE_FILE_LSHIFT3)	+ \
+	 pte_bfop((pte).pte_low, PTE_FILE_SHIFT4, PTE_FILE_NOMASK, PTE_FILE_LSHIFT4))
+
+#define pgoff_to_pte(off)							  \
+	((pte_t) { .pte_low =							  \
+	pte_bfop(off,                0, PTE_FILE_MASK1, PTE_FILE_SHIFT1)	+ \
+	pte_bfop(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2, PTE_FILE_SHIFT2)	+ \
+	pte_bfop(off, PTE_FILE_LSHIFT3, PTE_FILE_MASK3, PTE_FILE_SHIFT3)	+ \
+	pte_bfop(off, PTE_FILE_LSHIFT4, PTE_FILE_NOMASK, PTE_FILE_SHIFT4)	+ \
 	_PAGE_FILE })
 
 #else /* CONFIG_MEM_SOFT_DIRTY */
@@ -120,16 +123,16 @@ static inline pmd_t native_pmdp_get_and_
 #define PTE_FILE_LSHIFT2	(PTE_FILE_BITS1)
 #define PTE_FILE_LSHIFT3	(PTE_FILE_BITS1 + PTE_FILE_BITS2)
 
-#define pte_to_pgoff(pte)							    \
-	(_mfrob((pte).pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1, 0)		  + \
-	 _mfrob((pte).pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2, PTE_FILE_LSHIFT2) + \
-	 __frob((pte).pte_low, PTE_FILE_SHIFT3, PTE_FILE_LSHIFT3))
-
-#define pgoff_to_pte(off)							\
-	((pte_t) { .pte_low =							\
-	_mfrob(off,                0, PTE_FILE_MASK1, PTE_FILE_SHIFT1)	+	\
-	_mfrob(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2, PTE_FILE_SHIFT2)	+	\
-	__frob(off, PTE_FILE_LSHIFT3, PTE_FILE_SHIFT3)			+	\
+#define pte_to_pgoff(pte)								  \
+	(pte_bfop((pte).pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1, 0)			+ \
+	 pte_bfop((pte).pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2, PTE_FILE_LSHIFT2)	+ \
+	 pte_bfop((pte).pte_low, PTE_FILE_SHIFT3, PTE_FILE_NOMASK, PTE_FILE_LSHIFT3))
+
+#define pgoff_to_pte(off)							  \
+	((pte_t) { .pte_low =							  \
+	pte_bfop(off,                0, PTE_FILE_MASK1, PTE_FILE_SHIFT1)	+ \
+	pte_bfop(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2, PTE_FILE_SHIFT2)	+ \
+	pte_bfop(off, PTE_FILE_LSHIFT3, PTE_FILE_NOMASK, PTE_FILE_SHIFT3)	+ \
 	_PAGE_FILE })
 
 #endif /* CONFIG_MEM_SOFT_DIRTY */

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#2 lore raw
Quoted 4 lines · H. Peter Anvin
Quoted 1 line · Cyrill Gorcunov

+#define pte_bfop(v,r,m,l) ((((v) >> (r)) & (m)) << (l))

"bfop"?

B_it_F_ield_OP_eration, Peter I don't mind to use any other name, this was just short enough to type.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#3 lore raw
Quoted 9 lines · Cyrill Gorcunov
Quoted 4 lines · H. Peter Anvin
Quoted 1 line · Cyrill Gorcunov

+#define pte_bfop(v,r,m,l) ((((v) >> (r)) & (m)) << (l))

"bfop"?

B_it_F_ield_OP_eration, Peter I don't mind to use any other name, this was just short enough to type.

I think it would be useful to have a comment what it means and what v,r,m,l represent.

Perhaps m should be mask width rather than the actual mask?

-hpa

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

maintainer
#4 lore raw
Quoted 5 lines · On Wed, 14 Aug 2013 00:31:12 -0700 "H. Peter Anvin" <[email protected]> wrote:
Quoted 4 lines · Cyrill Gorcunov
Quoted 3 lines · H. Peter Anvin
Quoted 1 line · Cyrill Gorcunov

+#define pte_bfop(v,r,m,l) ((((v) >> (r)) & (m)) << (l))

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

"bfop"?

B_it_F_ield_OP_eration, Peter I don't mind to use any other name, this was just short enough to type.

I think it would be useful to have a comment what it means and what v,r,m,l represent.

Can it be written in C with types and proper variable names and such radical stuff?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#5 lore raw
Quoted 6 lines · Andrew Morton
Quoted 6 lines
Quoted 3 lines

B_it_F_ield_OP_eration, Peter I don't mind to use any other name, this was just short enough to type.

I think it would be useful to have a comment what it means and what v,r,m,l represent.

Sure, maybe simply better names as value, rshift, mask, lshift would look more understandable. I'll try to use width for mask as well (which reminds me BFEXT helpers Andrew mentioned in this thread).

Quoted 2 lines

Can it be written in C with types and proper variable names and such radical stuff?

Could you elaborate? You mean inline helper or macro with type checks?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

maintainer
#6 lore raw
Quoted 8 lines · On Wed, 14 Aug 2013 11:43:33 +0400 Cyrill Gorcunov <[email protected]> wrote:
Quoted 6 lines · Andrew Morton
Quoted 6 lines
Quoted 3 lines

B_it_F_ield_OP_eration, Peter I don't mind to use any other name, this was just short enough to type.

I think it would be useful to have a comment what it means and what v,r,m,l represent.

Quoted 8 lines

Sure, maybe simply better names as value, rshift, mask, lshift would look more understandable. I'll try to use width for mask as well (which reminds me BFEXT helpers Andrew mentioned in this thread).

Quoted 2 lines

Can it be written in C with types and proper variable names and such radical stuff?

Could you elaborate? You mean inline helper or macro with type checks?

/*
* description goes here
*/
static inline pteval_t pte_bfop(pteval_t val, int rightshift, ...)

{
	...
}

So much better! We really should only implement code in a macro if it *has* to be done as a macro and I don't think that's the case here?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw
Quoted 10 lines · Andrew Morton
Quoted 5 lines
Quoted 3 lines

Can it be written in C with types and proper variable names and such radical stuff?

Could you elaborate? You mean inline helper or macro with type checks?

/*
* description goes here
*/
static inline pteval_t pte_bfop(pteval_t val, int rightshift, ...)

Quoted 6 lines
{
	...
}

So much better! We really should only implement code in a macro if it *has* to be done as a macro and I don't think that's the case here?

Well, I'll have to check if it really doesn't generate additional instructions in generated code, since it's hotpath. I'll ping back once things are done.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#8 lore raw
Quoted 15 lines · Cyrill Gorcunov
Quoted 14 lines · Andrew Morton
Quoted 5 lines
Quoted 3 lines

Can it be written in C with types and proper variable names and such radical stuff?

Could you elaborate? You mean inline helper or macro with type checks?

/*
* description goes here
*/
static inline pteval_t pte_bfop(pteval_t val, int rightshift, ...)

{
	...
}
Quoted 6 lines
Quoted 2 lines

So much better! We really should only implement code in a macro if it *has* to be done as a macro and I don't think that's the case here?

Well, I'll have to check if it really doesn't generate additional instructions in generated code, since it's hotpath. I'll ping back once things are done.

An __always_inline should never do that.

Thanks,

Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#9 lore raw
Quoted 6 lines · Ingo Molnar
Quoted 4 lines

Well, I'll have to check if it really doesn't generate additional instructions in generated code, since it's hotpath. I'll ping back once things are done.

An __always_inline should never do that.

Here is the final one, please ping me if something looks not as clean as it wanted to be and i'll tune code up, thanks!

To hpa@: I had to use explicit @mask because it allows to pass -1ul mask which is optimized off then by a compiler.
---
From: Cyrill Gorcunov <[email protected]>
Subject: [PATCH -mm] mm: Unify pte_to_pgoff and pgoff_to_pte helpers

Use unified pte_bfop helper to manipulate bits in pte/pgoff bitfield, and convert pte_to_pgoff/pgoff_to_pte to inlines.

Cc Andrew Morton <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc "H. Peter Anvin" <[email protected]>
Cc Pavel Emelyanov <[email protected]>
Cc Matt Mackall <[email protected]>
Cc Xiao Guangrong <[email protected]>
Cc Marcelo Tosatti <[email protected]>
Cc KOSAKI Motohiro <[email protected]>
Cc Stephen Rothwell <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc "Aneesh Kumar K.V" <[email protected]>
---
 arch/x86/include/asm/pgtable-2level.h |   70 +++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 26 deletions(-)
arch/x86/include/asm/pgtable-2level.h +44 -26
Index: linux-2.6.git/arch/x86/include/asm/pgtable-2level.h
===================================================================
@@ -55,8 +55,12 @@ static inline pmd_t native_pmdp_get_and_
 #define native_pmdp_get_and_clear(xp) native_local_pmdp_get_and_clear(xp)
 #endif
 
-#define _mfrob(v,r,m,l)		((((v) >> (r)) & (m)) << (l))
-#define __frob(v,r,l)		(((v) >> (r)) << (l))
+/* Bit manipulation helper on pte/pgoff entry */
+static inline unsigned long pte_bfop(unsigned long value, unsigned int rightshift,
+				     unsigned long mask, unsigned int leftshift)
+{
+	return ((value >> rightshift) & mask) << leftshift;
+}
 
 #ifdef CONFIG_MEM_SOFT_DIRTY
 
@@ -82,19 +86,26 @@ static inline pmd_t native_pmdp_get_and_
 #define PTE_FILE_LSHIFT3	(PTE_FILE_BITS1 + PTE_FILE_BITS2)
 #define PTE_FILE_LSHIFT4	(PTE_FILE_BITS1 + PTE_FILE_BITS2 + PTE_FILE_BITS3)
 
-#define pte_to_pgoff(pte)							    \
-	(_mfrob((pte).pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1, 0)		  + \
-	 _mfrob((pte).pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2, PTE_FILE_LSHIFT2) + \
-	 _mfrob((pte).pte_low, PTE_FILE_SHIFT3, PTE_FILE_MASK3, PTE_FILE_LSHIFT3) + \
-	 __frob((pte).pte_low, PTE_FILE_SHIFT4, PTE_FILE_LSHIFT4))
-
-#define pgoff_to_pte(off)							\
-	((pte_t) { .pte_low =							\
-	_mfrob(off,                0, PTE_FILE_MASK1, PTE_FILE_SHIFT1)	+	\
-	_mfrob(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2, PTE_FILE_SHIFT2)	+	\
-	_mfrob(off, PTE_FILE_LSHIFT3, PTE_FILE_MASK3, PTE_FILE_SHIFT3)	+	\
-	__frob(off, PTE_FILE_LSHIFT4, PTE_FILE_SHIFT4)			+	\
-	_PAGE_FILE })
+static __always_inline pgoff_t pte_to_pgoff(pte_t pte)
+{
+	return (pgoff_t)
+		(pte_bfop(pte.pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1,  0)		   +
+		 pte_bfop(pte.pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2,  PTE_FILE_LSHIFT2) +
+		 pte_bfop(pte.pte_low, PTE_FILE_SHIFT3, PTE_FILE_MASK3,  PTE_FILE_LSHIFT3) +
+		 pte_bfop(pte.pte_low, PTE_FILE_SHIFT4,           -1UL,  PTE_FILE_LSHIFT4));
+}
+
+static __always_inline pte_t pgoff_to_pte(pgoff_t off)
+{
+	return (pte_t){
+		.pte_low =
+			pte_bfop(off,                0, PTE_FILE_MASK1,  PTE_FILE_SHIFT1) +
+			pte_bfop(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2,  PTE_FILE_SHIFT2) +
+			pte_bfop(off, PTE_FILE_LSHIFT3, PTE_FILE_MASK3,  PTE_FILE_SHIFT3) +
+			pte_bfop(off, PTE_FILE_LSHIFT4,           -1UL,  PTE_FILE_SHIFT4) +
+			_PAGE_FILE,
+	};
+}
 
 #else /* CONFIG_MEM_SOFT_DIRTY */
 
@@ -120,17 +131,24 @@ static inline pmd_t native_pmdp_get_and_
 #define PTE_FILE_LSHIFT2	(PTE_FILE_BITS1)
 #define PTE_FILE_LSHIFT3	(PTE_FILE_BITS1 + PTE_FILE_BITS2)
 
-#define pte_to_pgoff(pte)							    \
-	(_mfrob((pte).pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1, 0)		  + \
-	 _mfrob((pte).pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2, PTE_FILE_LSHIFT2) + \
-	 __frob((pte).pte_low, PTE_FILE_SHIFT3, PTE_FILE_LSHIFT3))
-
-#define pgoff_to_pte(off)							\
-	((pte_t) { .pte_low =							\
-	_mfrob(off,                0, PTE_FILE_MASK1, PTE_FILE_SHIFT1)	+	\
-	_mfrob(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2, PTE_FILE_SHIFT2)	+	\
-	__frob(off, PTE_FILE_LSHIFT3, PTE_FILE_SHIFT3)			+	\
-	_PAGE_FILE })
+static __always_inline pgoff_t pte_to_pgoff(pte_t pte)
+{
+	return (pgoff_t)
+		(pte_bfop(pte.pte_low, PTE_FILE_SHIFT1, PTE_FILE_MASK1,  0)		   +
+		 pte_bfop(pte.pte_low, PTE_FILE_SHIFT2, PTE_FILE_MASK2,  PTE_FILE_LSHIFT2) +
+		 pte_bfop(pte.pte_low, PTE_FILE_SHIFT3,           -1UL,  PTE_FILE_LSHIFT3));
+}
+
+static __always_inline pte_t pgoff_to_pte(pgoff_t off)
+{
+	return (pte_t){
+		.pte_low =
+			pte_bfop(off,                0, PTE_FILE_MASK1,  PTE_FILE_SHIFT1) +
+			pte_bfop(off, PTE_FILE_LSHIFT2, PTE_FILE_MASK2,  PTE_FILE_SHIFT2) +
+			pte_bfop(off, PTE_FILE_LSHIFT3,           -1UL,  PTE_FILE_SHIFT3) +
+			_PAGE_FILE,
+	};
+}
 
 #endif /* CONFIG_MEM_SOFT_DIRTY */
 

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>