Messages in this thread | | | Date | Wed, 25 Oct 2023 17:05:13 +0200 | From | Vasily Gorbik <> | Subject | Re: [PATCH v4 1/3] math.h: add DIV_ROUND_UP_NO_OVERFLOW |
| |
On Tue, Oct 24, 2023 at 12:53:03PM -1000, Linus Torvalds wrote: >+/* >+ * The other cases need to be split by type. >+ * >+ * Signed cases seem badly defined, but do exist. We should >+ * consider removing them from this _Generic(), and fixing any >+ * result 'not compatible with any association' cases. >+ */ >+#define __div_round_up(n,d) _Generic((n)+(d), \ >+ unsigned long long: __div_round_up_ull(n,d), \ >+ long long: __div_round_up_ll(n,d), \ >+ unsigned long: __div_round_up_ul(n,d), \ >+ long: __div_round_up_l(n,d), \ >+ unsigned int: __div_round_up_u(n,d), \ >+ int: __div_round_up_i(n,d))
You probably want
#define __div_round_up(n,d) _Generic((n)+(d), \ unsigned long long: __div_round_up_ull, \ long long: __div_round_up_ll, \ unsigned long: __div_round_up_ul, \ long: __div_round_up_l, \ unsigned int: __div_round_up_u, \ int: __div_round_up_i)(n,d)
to avoid early type-checking for expressions that will be discarded and prevent errors like:
drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c: In function 'sparx5_tc_flower_parse_act_police': drivers/net/ethernet/microchip/sparx5/sparx5_main.h:435:34: error: conversion from 'long long unsigned int' to 'long unsigned int' changes value from '25000000000' to '3525163520' [-Werror=overflow] 435 | #define SPX5_SDLB_GROUP_RATE_MAX 25000000000ULL | ^~~~~~~~~~~~~~ ./include/linux/div_round_up.h:68:42: note: in definition of macro '__div_round_up' 68 | unsigned long: __div_round_up_ul(n,d), \ | ^ ./include/linux/div_round_up.h:50:9: note: in expansion of macro '__keep_const' 50 | __keep_const(n, div_round_up(n,d)) | ^~~~~~~~~~~~ ./include/linux/math.h:37:22: note: in expansion of macro '__KERNEL_DIV_ROUND_UP' 37 | #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP | ^~~~~~~~~~~~~~~~~~~~~ drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c:732:38: note: in expansion of macro 'SPX5_SDLB_GROUP_RATE_MAX' 732 | if (pol->rate > DIV_ROUND_UP(SPX5_SDLB_GROUP_RATE_MAX, 1000)) { | ^~~~~~~~~~~~~~~~~~~~~~~~ drivers/net/ethernet/microchip/sparx5/sparx5_main.h:435:34: error: overflow in conversion from 'long long unsigned int' to 'long int' changes value from '25000000000' to '-769803776' [-Werror=overflow] ... drivers/net/ethernet/microchip/sparx5/sparx5_main.h:435:34: error: conversion from 'long long unsigned int' to 'unsigned int' changes value from '25000000000' to '3525163520' [-Werror=overflow] ... drivers/net/ethernet/microchip/sparx5/sparx5_main.h:435:34: error: overflow in conversion from 'long long unsigned int' to 'int' changes value from '25000000000' to '-769803776' [-Werror=overflow]
Plus typos fixes below passes allyesconfig for s390, 32-bit x86 and arm.
static inline unsigned long long __div_round_up_ull(unsigned long long n, unsigned long d) { #ifdef CONFIG_32BIT if (!n) - return 0 - do_div(n-1, d); - return n+1; + return 0; + n--; + do_div(n, d); + return n + 1; #else return __const_div_round_up(n,d); #endif
| |