Re: [PATCH] kernel.h: add IS_PTR_ALIGNED() macro
From: H. Peter Anvin
Date: Wed Mar 29 2017 - 17:39:00 EST
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@xxxxxxxxxxxxx>
> ---
>
> 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; })))))