diff mbox

kernel.h: add IS_PTR_ALIGNED() macro

Message ID 1490782930-30429-1-git-send-email-yamada.masahiro@socionext.com
State New
Headers show

Commit Message

Masahiro Yamada March 29, 2017, 10:22 a.m. UTC
We often check if a pointer has a specific alignment.  Because the
'&' (bitwise AND) operator cannot take a pointer for the operand,
so we need a cast like, IS_ALIGNED((unsigned long)p, a).

IS_PTR_ALIGNED will be useful as a shorthand.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

---

 include/linux/kernel.h | 1 +
 1 file changed, 1 insertion(+)

-- 
2.7.4

Comments

H. Peter Anvin March 29, 2017, 9:24 p.m. UTC | #1
On 03/29/17 03:22, Masahiro Yamada wrote:
> We often check if a pointer has a specific alignment.  Because the

> '&' (bitwise AND) operator cannot take a pointer for the operand,

> so we need a cast like, IS_ALIGNED((unsigned long)p, a).

> 

> IS_PTR_ALIGNED will be useful as a shorthand.

> 

> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

> ---

> 

>  include/linux/kernel.h | 1 +

>  1 file changed, 1 insertion(+)

> 

> diff --git a/include/linux/kernel.h b/include/linux/kernel.h

> index e5edd55..a810e4b 100644

> --- a/include/linux/kernel.h

> +++ b/include/linux/kernel.h

> @@ -50,6 +50,7 @@

>  #define __ALIGN_MASK(x, mask)	__ALIGN_KERNEL_MASK((x), (mask))

>  #define PTR_ALIGN(p, a)		((typeof(p))ALIGN((unsigned long)(p), (a)))

>  #define IS_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)

> +#define IS_PTR_ALIGNED(p, a)		(IS_ALIGNED((unsigned long)p, a))

>  


No need for two macros; make one work for both.

You could move the __inttype() macro from arch/x86/include/asm/uaccess.h
into this file and replace typeof(x) with __inttype(x) in the above macro.

Attached is a set of slightly improved (safer and a bit more
generalized) versions of the same macro that might be more appropriate
to include in <linux/kernel.h>.

	-hpa
/*
 * These are types: corresponding to the smallest unsigned/signed
 * integer type no smaller than int or long, respectively, capable of
 * holding the argument (which can be anything that can be validly
 * passed to sizeof().)
 *
 * If the size is too large even for a long long, they return an
 * unnamed structure type with the right sizeof(), which if used for a
 * cast will generate the error message:
 *
 * error: conversion to non-scalar type requested
 */
#define __uinttype(x)							\
  __typeof__(__builtin_choose_expr(sizeof(x) <= sizeof(0U), 0U,		\
             __builtin_choose_expr(sizeof(x) <= sizeof(0UL), 0UL,	\
	     __builtin_choose_expr(sizeof(x) <= sizeof(0ULL), 0ULL,	\
	     ({ struct { unsigned char __bad[sizeof(x)]; } __bad = {{0}}; \
	        __bad; })))))
#define __sinttype(x)							\
  __typeof__(__builtin_choose_expr(sizeof(x) <= sizeof(0), 0,		\
             __builtin_choose_expr(sizeof(x) <= sizeof(0L), 0L,		\
	     __builtin_choose_expr(sizeof(x) <= sizeof(0LL), 0LL,	\
	     ({ struct { signed char __bad[sizeof(x)]; } __bad = {{0}}; \
	        __bad; })))))
#define __ulongtype(x)							\
  __typeof__(__builtin_choose_expr(sizeof(x) <= sizeof(0UL), 0UL,	\
	     __builtin_choose_expr(sizeof(x) <= sizeof(0ULL), 0ULL,	\
	     ({ struct { unsigned char __bad[sizeof(x)]; } __bad = {{0}}; \
	        __bad; }))))
#define __slongtype(x)							\
  __typeof__(__builtin_choose_expr(sizeof(x) <= sizeof(0L), 0L,		\
	     __builtin_choose_expr(sizeof(x) <= sizeof(0LL), 0LL,	\
	     ({ struct { signed char __bad[sizeof(x)]; } __bad = {{0}}; \
	        __bad; })))))
Andrew Morton March 29, 2017, 9:36 p.m. UTC | #2
On Wed, 29 Mar 2017 19:22:10 +0900 Masahiro Yamada <yamada.masahiro@socionext.com> wrote:

> We often check if a pointer has a specific alignment.  Because the

> '&' (bitwise AND) operator cannot take a pointer for the operand,

> so we need a cast like, IS_ALIGNED((unsigned long)p, a).

> 

> IS_PTR_ALIGNED will be useful as a shorthand.

> 

> ...

>

> --- a/include/linux/kernel.h

> +++ b/include/linux/kernel.h

> @@ -50,6 +50,7 @@

>  #define __ALIGN_MASK(x, mask)	__ALIGN_KERNEL_MASK((x), (mask))

>  #define PTR_ALIGN(p, a)		((typeof(p))ALIGN((unsigned long)(p), (a)))

>  #define IS_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)

> +#define IS_PTR_ALIGNED(p, a)		(IS_ALIGNED((unsigned long)p, a))

>  

>  /* generic data direction definitions */

>  #define READ			0


It would be nice to see some conversions which actually use this new
macro.
Masahiro Yamada March 30, 2017, 1:57 a.m. UTC | #3
Hi.

2017-03-30 6:24 GMT+09:00 H. Peter Anvin <hpa@zytor.com>:
> On 03/29/17 03:22, Masahiro Yamada wrote:

>> We often check if a pointer has a specific alignment.  Because the

>> '&' (bitwise AND) operator cannot take a pointer for the operand,

>> so we need a cast like, IS_ALIGNED((unsigned long)p, a).

>>

>> IS_PTR_ALIGNED will be useful as a shorthand.

>>

>> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

>> ---

>>

>>  include/linux/kernel.h | 1 +

>>  1 file changed, 1 insertion(+)

>>

>> diff --git a/include/linux/kernel.h b/include/linux/kernel.h

>> index e5edd55..a810e4b 100644

>> --- a/include/linux/kernel.h

>> +++ b/include/linux/kernel.h

>> @@ -50,6 +50,7 @@

>>  #define __ALIGN_MASK(x, mask)        __ALIGN_KERNEL_MASK((x), (mask))

>>  #define PTR_ALIGN(p, a)              ((typeof(p))ALIGN((unsigned long)(p), (a)))

>>  #define IS_ALIGNED(x, a)             (((x) & ((typeof(x))(a) - 1)) == 0)

>> +#define IS_PTR_ALIGNED(p, a)         (IS_ALIGNED((unsigned long)p, a))

>>

>

> No need for two macros; make one work for both.

>

> You could move the __inttype() macro from arch/x86/include/asm/uaccess.h

> into this file and replace typeof(x) with __inttype(x) in the above macro.

>

> Attached is a set of slightly improved (safer and a bit more

> generalized) versions of the same macro that might be more appropriate

> to include in <linux/kernel.h>.

>

>         -hpa



Could you care to send a patch?

Perhaps, ALIGN and PTR_ALIGN can be merged as well?



-- 
Best Regards
Masahiro Yamada
H. Peter Anvin March 30, 2017, 3:29 a.m. UTC | #4
On 03/29/17 18:57, Masahiro Yamada wrote:
> 

> Could you care to send a patch?

> 

> Perhaps, ALIGN and PTR_ALIGN can be merged as well?

> 


Can't promise when I'd get around to it...

	-hpa
Masahiro Yamada March 30, 2017, 3:22 p.m. UTC | #5
Hi.

2017-03-30 12:29 GMT+09:00 H. Peter Anvin <hpa@zytor.com>:
> On 03/29/17 18:57, Masahiro Yamada wrote:

>>

>> Could you care to send a patch?

>>

>> Perhaps, ALIGN and PTR_ALIGN can be merged as well?

>>

>

> Can't promise when I'd get around to it...

>

>         -hpa


OK. No need to rush now.
Please take a look when you find some time.


Andrew,
Maybe, we should drop my patch for now,
and take our time for better implementation?





-- 
Best Regards
Masahiro Yamada
diff mbox

Patch

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index e5edd55..a810e4b 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -50,6 +50,7 @@ 
 #define __ALIGN_MASK(x, mask)	__ALIGN_KERNEL_MASK((x), (mask))
 #define PTR_ALIGN(p, a)		((typeof(p))ALIGN((unsigned long)(p), (a)))
 #define IS_ALIGNED(x, a)		(((x) & ((typeof(x))(a) - 1)) == 0)
+#define IS_PTR_ALIGNED(p, a)		(IS_ALIGNED((unsigned long)p, a))
 
 /* generic data direction definitions */
 #define READ			0