All of lore.kernel.org
 help / color / mirror / Atom feed
From: Randy Dunlap <rdunlap@infradead.org>
To: Anatol Pomozov <anatol.pomozov@gmail.com>
Cc: LKML <linux-kernel@vger.kernel.org>, Tejun Heo <tj@kernel.org>,
	bernie@develer.com
Subject: Re: do_div() silently truncates "base" to 32bit
Date: Fri, 30 Aug 2013 14:23:00 -0700	[thread overview]
Message-ID: <52210D34.5030807@infradead.org> (raw)
In-Reply-To: <CAOMFOmXfw2DkesOYip9VFDdUQgVN48qbJfuertPaSCz5aGdaeA@mail.gmail.com>

On 08/30/13 10:21, Anatol Pomozov wrote:
> Hi,
> 
> 
> I was debugging weird "zero divide" problem in CFQ code below
> 
> 
> static u64 cfqg_prfill_avg_queue_size(struct seq_file *sf,
>       struct blkg_policy_data *pd, int off)
> {
>     struct cfq_group *cfqg = pd_to_cfqg(pd);
>     u64 samples = blkg_stat_read(&cfqg->stats.avg_queue_size_samples);
>     u64 v = 0;
> 
>     if (samples) {
>         v = blkg_stat_read(&cfqg->stats.avg_queue_size_sum);
>         do_div(v, samples);
>     }
>     __blkg_prfill_u64(sf, pd, v);
>     return 0;
> }
> 
> 
> do_div() crashes says "zero divide". It is weird because just a few
> lines above we check divider for zero.
> 
> 
> The problem comes from include/asm-generic/div64.h file that
> implements do_div() as macros:
> 
> # define do_div(n,base) ({ \
>     uint32_t __base = (base); \
>     uint32_t __rem; \
>     __rem = ((uint64_t)(n)) % __base; \
>     (n) = ((uint64_t)(n)) / __base; \
>     __rem; \
>  })
> 
> 
> Do you see the problem?
> 
> The problem here is that "base" argument is truncated to 32bit, but in
> the function above "sample" is 64bit variable. If sample's 32 low bits
> are zero - we have a crash. in fact we have incorrect behavior any
> time when high 32bits are non-zero.
> 
> 
> My question is why the base is 32bit? Why not to use 64bit arguments?

Maybe performance related?

If you want 64-bit values, don't use do_div() from asm-generic/div64.h.

Instead look at linux/math64.h and use div_u64_rem() et al
or the recently posted div64_u64_rem().
[posted by Mike Snitzer on Aug. 21 2013]

I.e., use exactly the function(s) that you need to use.

Does that fix the problem?


> Ideally if this macros is converted to a function so compiler will
> warn us about unexpected truncation like this. But in this case it
> will be hard to do as "n" parameter both input and output.
> --


-- 
~Randy

  reply	other threads:[~2013-08-30 21:23 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-30 17:21 do_div() silently truncates "base" to 32bit Anatol Pomozov
2013-08-30 21:23 ` Randy Dunlap [this message]
2013-08-30 22:14   ` Anatol Pomozov
2013-08-30 22:48     ` Randy Dunlap
2013-08-30 23:28       ` Joe Perches
2013-08-31  0:50         ` Anatol Pomozov
2013-09-04 15:32           ` Anatol Pomozov
2013-09-04 17:20             ` Randy Dunlap
2013-10-08 16:10 ` [PATCH] core: Catch overflows in do_div() function Anatol Pomozov
2013-10-08 16:18   ` Joe Perches
2013-10-08 16:45     ` Richard Weinberger
2013-10-08 16:51       ` Joe Perches
2013-10-08 17:28       ` Anatol Pomozov
2013-10-08 17:40         ` Anatol Pomozov
2013-10-08 17:15   ` Eric Dumazet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52210D34.5030807@infradead.org \
    --to=rdunlap@infradead.org \
    --cc=anatol.pomozov@gmail.com \
    --cc=bernie@develer.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.