[PATCH 1/2] [PATCH 1/2] Introduce new macros min_lt and max_lt for comparing with larger type

Dave Young dyoung at redhat.com
Thu Mar 10 23:55:06 PST 2016


Hi, Jianyu

On 03/11/16 at 03:19pm, Jianyu Zhan wrote:
> On Fri, Mar 11, 2016 at 2:21 PM,  <dyoung at redhat.com> wrote:
> > A useful use case for min_t and max_t is comparing two values with larger
> > type. For example comparing an u64 and an u32, usually we do not want to
> > truncate the u64, so we need use min_t or max_t with u64.
> >
> > To simplify the usage introducing two more macros min_lt and max_lt,
> > 'lt' means larger type.
> >
> > Signed-off-by: Dave Young <dyoung at redhat.com>
> > ---
> >  include/linux/kernel.h |   13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> >
> > --- linux.orig/include/linux/kernel.h
> > +++ linux/include/linux/kernel.h
> > @@ -798,6 +798,19 @@ static inline void ftrace_dump(enum ftra
> >         type __max2 = (y);                      \
> >         __max1 > __max2 ? __max1: __max2; })
> >
> > +/*
> > + * use type of larger size in min_lt and max_lt
> > + */
> > +#define min_lt(x, y) ({                        \
> > +       int sx = sizeof(typeof(x));             \
> > +       int sy = sizeof(typeof(y));             \
> > +       sx > sy ? min_t(typeof(x), x, y) : min_t(typeof(y), x, y); })
> > +
> > +#define max_lt(x, y) ({                        \
> > +       int sx = sizeof(typeof(x));             \
> > +       int sy = sizeof(typeof(y));             \
> > +       sx > sy ? max_t(typeof(x), x, y) : max_t(typeof(y), x, y); })
> > +
> >  /**
> >   * clamp_t - return a value clamped to a given range using a given type
> >   * @type: the type of variable to use
> >
> >
> 
> No no!
> 
> C standard has defined "usual arithmetic conversions" rules[1], which
> decides the type promotion rules in binary operators.
> 
> The interfaces in this patch just bluntly overrides this rule to
> choose the bigger type size
> for operation.  Most of time it might work well, because most time the
> operands used in min_t()/max_t() in Linux kernel
> have same sign'ness and this rule works.
> 
> But if two operands have same size type but have different different
> sign'ness,  this interfaces will exhibit Undefind Behavior,
> i.e.  you choose the typeof(y) as the final type to use in operation
> when they have the same type size,  so it might be signed
> or unsigned, depending on the type of y.

Oops, brain dead, I obviously missed the case, it is definitely a problem.

> 
> So,  in this /proc/fs/vmcore case you should rather just explicit cast
> the operand to avoid truncation.

Sure, will resend a fix

Thanks
Dave



More information about the kexec mailing list