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 15:48:08 -0700 [thread overview]
Message-ID: <52212128.3000100@infradead.org> (raw)
In-Reply-To: <CAOMFOmUav+3UqR9s5LF6n4c4oXZ-K5oBJrmLtz-PMY053vH8Rg@mail.gmail.com>
On 08/30/13 15:14, Anatol Pomozov wrote:
> Hi
>
> On Fri, Aug 30, 2013 at 2:23 PM, Randy Dunlap <rdunlap@infradead.org> wrote:
>> 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?
>
> It definitely fixes the crash. I've already sent a patch to CFQ
> maillist http://news.gmane.org/gmane.linux.kernel.cgroups
>
> But another question still remains: why compiler does not warn that
> size truncation happens? How to prevent bugs like CFQ one in the
> future? Should we add a compile-time assert to do_div() to prevent
> passing 64 numbers in "base" macro parameter?
That sounds like a fine idea to me.
--
~Randy
next prev parent reply other threads:[~2013-08-30 22:48 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
2013-08-30 22:14 ` Anatol Pomozov
2013-08-30 22:48 ` Randy Dunlap [this message]
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=52212128.3000100@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.