Re: [RFC][PATCH] kernel.h: Add generic roundup_64() macro

From: Linus Torvalds
Date: Thu May 23 2019 - 13:02:30 EST


On Thu, May 23, 2019 at 8:27 AM Steven Rostedt <rostedt@xxxxxxxxxxx> wrote:
>
> I haven't yet tested this, but what about something like the following:

So that at least handles the constant case that the normal "roundup()"
case also handles.

At the same time, in the case you are talking about, I really do
suspect that we have a (non-constant) power of two, and that you
should have just used "round_up()" which works fine regardless of
size, and is always efficient.

On a slight tangent.. Maybe we should have something like this:

#define size_fn(x, prefix, ...) ({ \
typeof(x) __ret; \
switch (sizeof(x)) { \
case 1: __ret = prefix##8(__VA_ARGS__); break; \
case 2: __ret = prefix##16(__VA_ARGS__); break; \
case 4: __ret = prefix##32(__VA_ARGS__); break; \
case 8: __ret = prefix##64(__VA_ARGS__); break; \
default: __ret = prefix##bad(__VA_ARGS__); \
} __ret; })

#define type_fn(x, prefix, ...) ({ \
typeof(x) __ret; \
if ((typeof(x))-1 > 1) \
__ret = size_fn(x, prefix##_u, __VA_ARGS__); \
else \
__ret = size_fn(x, prefix##_s, __VA_ARGS__); \
__ret; })

which would allow typed integer functions like this. So you could do
something like

#define round_up(x, y) size_fn(x, round_up_size, x, y)

and then you define functions for round_up_size8/16/32/64 (and you
have toi declare - but not define - round_up_sizebad()).

Of course, you probably want the usual "at least use 'int'" semantics,
in which case the "type" should be "(x)+0":

#define round_up(x, y) size_fn((x)+0, round_up_size, x, y)

and the 8-bit and 16-bit cases will never be used.

We have a lot of cases where we end up using "type overloading" by
size. The most explicit case is perhaps "get_user()" and "put_user()",
but this whole round_up thing is another example.

Maybe we never really care about "char" and "short", and always want
just the "int-vs-long-vs-longlong"? That would make the cases simpler
(32 and 64). And maybe we never care about sign. But we could try to
have some unified helper model like the above..

Linus