Re: [PATCH v2 1/8] kernel.h: Split out min()/max() et al. helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Aug 17, 2020 at 07:36:40PM +0300, Andy Shevchenko wrote:
> kernel.h is being used as a dump for all kinds of stuff for a long time.
> Here is the attempt to start cleaning it up by splitting out min()/max()
> et al. helpers.
> 
> At the same time convert users in header and lib folder to use new header.
> Though for time being include new header back to kernel.h to avoid twisted
> indirected includes for other existing users.

Rafael, does it look good now?

> Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
> ---
> v2: new patch, prerequisite for the rest (Rafael)
>  include/linux/blkdev.h    |   1 +
>  include/linux/bvec.h      |   6 +-
>  include/linux/jiffies.h   |   3 +-
>  include/linux/kernel.h    | 142 +------------------------------------
>  include/linux/minmax.h    | 145 ++++++++++++++++++++++++++++++++++++++
>  include/linux/nodemask.h  |   2 +-
>  include/linux/uaccess.h   |   1 +
>  kernel/range.c            |   3 +-
>  lib/find_bit.c            |   1 +
>  lib/hexdump.c             |   1 +
>  lib/math/rational.c       |   2 +-
>  lib/math/reciprocal_div.c |   1 +
>  12 files changed, 162 insertions(+), 146 deletions(-)
>  create mode 100644 include/linux/minmax.h
> 
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index bb5636cc17b9..3641c7234afb 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -8,6 +8,7 @@
>  #include <linux/genhd.h>
>  #include <linux/list.h>
>  #include <linux/llist.h>
> +#include <linux/minmax.h>
>  #include <linux/timer.h>
>  #include <linux/workqueue.h>
>  #include <linux/pagemap.h>
> diff --git a/include/linux/bvec.h b/include/linux/bvec.h
> index ac0c7299d5b8..8c7b3926b69c 100644
> --- a/include/linux/bvec.h
> +++ b/include/linux/bvec.h
> @@ -7,10 +7,14 @@
>  #ifndef __LINUX_BVEC_ITER_H
>  #define __LINUX_BVEC_ITER_H
>  
> -#include <linux/kernel.h>
>  #include <linux/bug.h>
>  #include <linux/errno.h>
> +#include <linux/limits.h>
> +#include <linux/minmax.h>
>  #include <linux/mm.h>
> +#include <linux/types.h>
> +
> +struct page;
>  
>  /**
>   * struct bio_vec - a contiguous range of physical memory addresses
> diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
> index fed6ba96c527..5e13f801c902 100644
> --- a/include/linux/jiffies.h
> +++ b/include/linux/jiffies.h
> @@ -3,8 +3,9 @@
>  #define _LINUX_JIFFIES_H
>  
>  #include <linux/cache.h>
> +#include <linux/limits.h>
>  #include <linux/math64.h>
> -#include <linux/kernel.h>
> +#include <linux/minmax.h>
>  #include <linux/types.h>
>  #include <linux/time.h>
>  #include <linux/timex.h>
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 500def620d8f..397f66bef709 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -11,6 +11,7 @@
>  #include <linux/compiler.h>
>  #include <linux/bitops.h>
>  #include <linux/log2.h>
> +#include <linux/minmax.h>
>  #include <linux/typecheck.h>
>  #include <linux/printk.h>
>  #include <linux/build_bug.h>
> @@ -834,147 +835,6 @@ ftrace_vprintk(const char *fmt, va_list ap)
>  static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
>  #endif /* CONFIG_TRACING */
>  
> -/*
> - * min()/max()/clamp() macros must accomplish three things:
> - *
> - * - avoid multiple evaluations of the arguments (so side-effects like
> - *   "x++" happen only once) when non-constant.
> - * - perform strict type-checking (to generate warnings instead of
> - *   nasty runtime surprises). See the "unnecessary" pointer comparison
> - *   in __typecheck().
> - * - retain result as a constant expressions when called with only
> - *   constant expressions (to avoid tripping VLA warnings in stack
> - *   allocation usage).
> - */
> -#define __typecheck(x, y) \
> -		(!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
> -
> -/*
> - * This returns a constant expression while determining if an argument is
> - * a constant expression, most importantly without evaluating the argument.
> - * Glory to Martin Uecker <Martin.Uecker@xxxxxxxxxxxxxxxxxxxxx>
> - */
> -#define __is_constexpr(x) \
> -	(sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
> -
> -#define __no_side_effects(x, y) \
> -		(__is_constexpr(x) && __is_constexpr(y))
> -
> -#define __safe_cmp(x, y) \
> -		(__typecheck(x, y) && __no_side_effects(x, y))
> -
> -#define __cmp(x, y, op)	((x) op (y) ? (x) : (y))
> -
> -#define __cmp_once(x, y, unique_x, unique_y, op) ({	\
> -		typeof(x) unique_x = (x);		\
> -		typeof(y) unique_y = (y);		\
> -		__cmp(unique_x, unique_y, op); })
> -
> -#define __careful_cmp(x, y, op) \
> -	__builtin_choose_expr(__safe_cmp(x, y), \
> -		__cmp(x, y, op), \
> -		__cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op))
> -
> -/**
> - * min - return minimum of two values of the same or compatible types
> - * @x: first value
> - * @y: second value
> - */
> -#define min(x, y)	__careful_cmp(x, y, <)
> -
> -/**
> - * max - return maximum of two values of the same or compatible types
> - * @x: first value
> - * @y: second value
> - */
> -#define max(x, y)	__careful_cmp(x, y, >)
> -
> -/**
> - * min3 - return minimum of three values
> - * @x: first value
> - * @y: second value
> - * @z: third value
> - */
> -#define min3(x, y, z) min((typeof(x))min(x, y), z)
> -
> -/**
> - * max3 - return maximum of three values
> - * @x: first value
> - * @y: second value
> - * @z: third value
> - */
> -#define max3(x, y, z) max((typeof(x))max(x, y), z)
> -
> -/**
> - * min_not_zero - return the minimum that is _not_ zero, unless both are zero
> - * @x: value1
> - * @y: value2
> - */
> -#define min_not_zero(x, y) ({			\
> -	typeof(x) __x = (x);			\
> -	typeof(y) __y = (y);			\
> -	__x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); })
> -
> -/**
> - * clamp - return a value clamped to a given range with strict typechecking
> - * @val: current value
> - * @lo: lowest allowable value
> - * @hi: highest allowable value
> - *
> - * This macro does strict typechecking of @lo/@hi to make sure they are of the
> - * same type as @val.  See the unnecessary pointer comparisons.
> - */
> -#define clamp(val, lo, hi) min((typeof(val))max(val, lo), hi)
> -
> -/*
> - * ..and if you can't take the strict
> - * types, you can specify one yourself.
> - *
> - * Or not use min/max/clamp at all, of course.
> - */
> -
> -/**
> - * min_t - return minimum of two values, using the specified type
> - * @type: data type to use
> - * @x: first value
> - * @y: second value
> - */
> -#define min_t(type, x, y)	__careful_cmp((type)(x), (type)(y), <)
> -
> -/**
> - * max_t - return maximum of two values, using the specified type
> - * @type: data type to use
> - * @x: first value
> - * @y: second value
> - */
> -#define max_t(type, x, y)	__careful_cmp((type)(x), (type)(y), >)
> -
> -/**
> - * clamp_t - return a value clamped to a given range using a given type
> - * @type: the type of variable to use
> - * @val: current value
> - * @lo: minimum allowable value
> - * @hi: maximum allowable value
> - *
> - * This macro does no typechecking and uses temporary variables of type
> - * @type to make all the comparisons.
> - */
> -#define clamp_t(type, val, lo, hi) min_t(type, max_t(type, val, lo), hi)
> -
> -/**
> - * clamp_val - return a value clamped to a given range using val's type
> - * @val: current value
> - * @lo: minimum allowable value
> - * @hi: maximum allowable value
> - *
> - * This macro does no typechecking and uses temporary variables of whatever
> - * type the input argument @val is.  This is useful when @val is an unsigned
> - * type and @lo and @hi are literals that will otherwise be assigned a signed
> - * integer type.
> - */
> -#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
> -
> -
>  /**
>   * swap - swap values of @a and @b
>   * @a: first value
> diff --git a/include/linux/minmax.h b/include/linux/minmax.h
> new file mode 100644
> index 000000000000..bfd6ad822914
> --- /dev/null
> +++ b/include/linux/minmax.h
> @@ -0,0 +1,145 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _LINUX_MINMAX_H
> +#define _LINUX_MINMAX_H
> +
> +/*
> + * min()/max()/clamp() macros must accomplish three things:
> + *
> + * - avoid multiple evaluations of the arguments (so side-effects like
> + *   "x++" happen only once) when non-constant.
> + * - perform strict type-checking (to generate warnings instead of
> + *   nasty runtime surprises). See the "unnecessary" pointer comparison
> + *   in __typecheck().
> + * - retain result as a constant expressions when called with only
> + *   constant expressions (to avoid tripping VLA warnings in stack
> + *   allocation usage).
> + */
> +#define __typecheck(x, y) \
> +	(!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
> +
> +/*
> + * This returns a constant expression while determining if an argument is
> + * a constant expression, most importantly without evaluating the argument.
> + * Glory to Martin Uecker <Martin.Uecker@xxxxxxxxxxxxxxxxxxxxx>
> + */
> +#define __is_constexpr(x) \
> +	(sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
> +
> +#define __no_side_effects(x, y) \
> +		(__is_constexpr(x) && __is_constexpr(y))
> +
> +#define __safe_cmp(x, y) \
> +		(__typecheck(x, y) && __no_side_effects(x, y))
> +
> +#define __cmp(x, y, op)	((x) op (y) ? (x) : (y))
> +
> +#define __cmp_once(x, y, unique_x, unique_y, op) ({	\
> +		typeof(x) unique_x = (x);		\
> +		typeof(y) unique_y = (y);		\
> +		__cmp(unique_x, unique_y, op); })
> +
> +#define __careful_cmp(x, y, op) \
> +	__builtin_choose_expr(__safe_cmp(x, y), \
> +		__cmp(x, y, op), \
> +		__cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op))
> +
> +/**
> + * min - return minimum of two values of the same or compatible types
> + * @x: first value
> + * @y: second value
> + */
> +#define min(x, y)	__careful_cmp(x, y, <)
> +
> +/**
> + * max - return maximum of two values of the same or compatible types
> + * @x: first value
> + * @y: second value
> + */
> +#define max(x, y)	__careful_cmp(x, y, >)
> +
> +/**
> + * min3 - return minimum of three values
> + * @x: first value
> + * @y: second value
> + * @z: third value
> + */
> +#define min3(x, y, z) min((typeof(x))min(x, y), z)
> +
> +/**
> + * max3 - return maximum of three values
> + * @x: first value
> + * @y: second value
> + * @z: third value
> + */
> +#define max3(x, y, z) max((typeof(x))max(x, y), z)
> +
> +/**
> + * min_not_zero - return the minimum that is _not_ zero, unless both are zero
> + * @x: value1
> + * @y: value2
> + */
> +#define min_not_zero(x, y) ({			\
> +	typeof(x) __x = (x);			\
> +	typeof(y) __y = (y);			\
> +	__x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); })
> +
> +/**
> + * clamp - return a value clamped to a given range with strict typechecking
> + * @val: current value
> + * @lo: lowest allowable value
> + * @hi: highest allowable value
> + *
> + * This macro does strict typechecking of @lo/@hi to make sure they are of the
> + * same type as @val.  See the unnecessary pointer comparisons.
> + */
> +#define clamp(val, lo, hi) min((typeof(val))max(val, lo), hi)
> +
> +/*
> + * ..and if you can't take the strict
> + * types, you can specify one yourself.
> + *
> + * Or not use min/max/clamp at all, of course.
> + */
> +
> +/**
> + * min_t - return minimum of two values, using the specified type
> + * @type: data type to use
> + * @x: first value
> + * @y: second value
> + */
> +#define min_t(type, x, y)	__careful_cmp((type)(x), (type)(y), <)
> +
> +/**
> + * max_t - return maximum of two values, using the specified type
> + * @type: data type to use
> + * @x: first value
> + * @y: second value
> + */
> +#define max_t(type, x, y)	__careful_cmp((type)(x), (type)(y), >)
> +
> +/**
> + * clamp_t - return a value clamped to a given range using a given type
> + * @type: the type of variable to use
> + * @val: current value
> + * @lo: minimum allowable value
> + * @hi: maximum allowable value
> + *
> + * This macro does no typechecking and uses temporary variables of type
> + * @type to make all the comparisons.
> + */
> +#define clamp_t(type, val, lo, hi) min_t(type, max_t(type, val, lo), hi)
> +
> +/**
> + * clamp_val - return a value clamped to a given range using val's type
> + * @val: current value
> + * @lo: minimum allowable value
> + * @hi: maximum allowable value
> + *
> + * This macro does no typechecking and uses temporary variables of whatever
> + * type the input argument @val is.  This is useful when @val is an unsigned
> + * type and @lo and @hi are literals that will otherwise be assigned a signed
> + * integer type.
> + */
> +#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
> +
> +#endif	/* _LINUX_MINMAX_H */
> diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
> index 27e7fa36f707..7f38399cc9fe 100644
> --- a/include/linux/nodemask.h
> +++ b/include/linux/nodemask.h
> @@ -90,9 +90,9 @@
>   * for such situations. See below and CPUMASK_ALLOC also.
>   */
>  
> -#include <linux/kernel.h>
>  #include <linux/threads.h>
>  #include <linux/bitmap.h>
> +#include <linux/minmax.h>
>  #include <linux/numa.h>
>  
>  typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;
> diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
> index ec980bbb786a..6d21d1d87a41 100644
> --- a/include/linux/uaccess.h
> +++ b/include/linux/uaccess.h
> @@ -3,6 +3,7 @@
>  #define __LINUX_UACCESS_H__
>  
>  #include <linux/instrumented.h>
> +#include <linux/minmax.h>
>  #include <linux/sched.h>
>  #include <linux/thread_info.h>
>  
> diff --git a/kernel/range.c b/kernel/range.c
> index d84de6766472..56435f96da73 100644
> --- a/kernel/range.c
> +++ b/kernel/range.c
> @@ -2,8 +2,9 @@
>  /*
>   * Range add and subtract
>   */
> -#include <linux/kernel.h>
>  #include <linux/init.h>
> +#include <linux/minmax.h>
> +#include <linux/printk.h>
>  #include <linux/sort.h>
>  #include <linux/string.h>
>  #include <linux/range.h>
> diff --git a/lib/find_bit.c b/lib/find_bit.c
> index 49f875f1baf7..4a8751010d59 100644
> --- a/lib/find_bit.c
> +++ b/lib/find_bit.c
> @@ -16,6 +16,7 @@
>  #include <linux/bitmap.h>
>  #include <linux/export.h>
>  #include <linux/kernel.h>
> +#include <linux/minmax.h>
>  
>  #if !defined(find_next_bit) || !defined(find_next_zero_bit) ||			\
>  	!defined(find_next_bit_le) || !defined(find_next_zero_bit_le) ||	\
> diff --git a/lib/hexdump.c b/lib/hexdump.c
> index 147133f8eb2f..9301578f98e8 100644
> --- a/lib/hexdump.c
> +++ b/lib/hexdump.c
> @@ -7,6 +7,7 @@
>  #include <linux/ctype.h>
>  #include <linux/errno.h>
>  #include <linux/kernel.h>
> +#include <linux/minmax.h>
>  #include <linux/export.h>
>  #include <asm/unaligned.h>
>  
> diff --git a/lib/math/rational.c b/lib/math/rational.c
> index df75c8809693..9781d521963d 100644
> --- a/lib/math/rational.c
> +++ b/lib/math/rational.c
> @@ -11,7 +11,7 @@
>  #include <linux/rational.h>
>  #include <linux/compiler.h>
>  #include <linux/export.h>
> -#include <linux/kernel.h>
> +#include <linux/minmax.h>
>  
>  /*
>   * calculate best rational approximation for a given fraction
> diff --git a/lib/math/reciprocal_div.c b/lib/math/reciprocal_div.c
> index bf043258fa00..32436dd4171e 100644
> --- a/lib/math/reciprocal_div.c
> +++ b/lib/math/reciprocal_div.c
> @@ -4,6 +4,7 @@
>  #include <asm/div64.h>
>  #include <linux/reciprocal_div.h>
>  #include <linux/export.h>
> +#include <linux/minmax.h>
>  
>  /*
>   * For a description of the algorithm please have a look at
> -- 
> 2.28.0
> 

-- 
With Best Regards,
Andy Shevchenko





[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux