Message ID | f522ad25-f899-4526-abc4-da35868b6a8b@p183 |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp1515208vqo; Fri, 19 May 2023 13:56:41 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6YYoEagGxWvAMgHm1O2EvJz2DQ89NVAFucvevbEmWLA7XgnYCOl0VWQzgAm5YmwXAmpPKF X-Received: by 2002:a05:6a20:a1a5:b0:105:27c3:1c0d with SMTP id r37-20020a056a20a1a500b0010527c31c0dmr2832476pzk.46.1684529801458; Fri, 19 May 2023 13:56:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684529801; cv=none; d=google.com; s=arc-20160816; b=p7u7QyoIdk2TxGL2jlzjwAOXCyGvMneiiFvcEntnL6V4LKSCD/jorVcDYv8kasn0WW Gc26NSbJv9AUlZOspQq0KU2u+uyWByZTbrh7fsamHjpQcJ/qXrxsjSIMdSDfrtikWkyQ jJmzAl8qOV+9iegT6jgVscKZexmkjnNOnwL8nTKEqQTSsFinIJnfPb+jdYrYo/gU65z1 rhPtzpISjR3XUgwOp7PLDuB4G2eQY+OuetbtwvXCfzYY2XGEmFjSTY3+fSc8AG9i3xZi dWgzynSSN6+PGNvFxGVRdRMFxEpdKP2d42DgEB2qD1oDCg166++nT0klLrozFkrpe5T8 zjMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-disposition:mime-version:message-id :subject:cc:to:from:date:dkim-signature; bh=Ip/4xPkpTBx2G+b4cQROiLf32EA1DGXtHtMtqI6ZZUw=; b=dxF8ZfiXf7+81/J2dm6Tk4PNd8vwc3LRaVIJWTM9arG4hDJknqe31cZOAKQagxqpD8 btPXhEq4VNWj3o3yu8zrvELzISHoqQ9D9++HOzZPZeDfBPoTrJ/DVCCW9j8t8Zcz+lWa AdYfmHCxercSM+7fj3FUh7dOKagg55ZjplOsCnZDbleBCkyuRj1lyUHtPQs5LyHNs6eL aO2XoYKFFSitAlp3HOhQlnOeP8xNrb6efVlebASBEqv0hZp7xLGHeDXne1B77SiIPUOp zwjfDNv7YpM3gfJv2ftQiYGTULVX7AuoGa4CPh/YR4FDRb2+iyiTVhSXQT4JvctgLAJ6 i4oQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b=I7tW7DWG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c4-20020a633504000000b0052c910d862fsi214856pga.244.2023.05.19.13.56.28; Fri, 19 May 2023 13:56:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20221208 header.b=I7tW7DWG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230319AbjESUZB (ORCPT <rfc822;wlfightup@gmail.com> + 99 others); Fri, 19 May 2023 16:25:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57856 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229458AbjESUZA (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 19 May 2023 16:25:00 -0400 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0CED6102 for <linux-kernel@vger.kernel.org>; Fri, 19 May 2023 13:24:59 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id ffacd0b85a97d-309553c5417so1084929f8f.2 for <linux-kernel@vger.kernel.org>; Fri, 19 May 2023 13:24:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1684527897; x=1687119897; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=Ip/4xPkpTBx2G+b4cQROiLf32EA1DGXtHtMtqI6ZZUw=; b=I7tW7DWG9caQ2bkDJa4MGSBCByIHkfGdAK5ObUMKKabXj/fS35qCfH6ORRJnVBmzva YkNd4AvHU89gJrNrFidCzOoazyKAkpQjApuxVFrLSKxAaKGzKWOoUCHj+HEG85yQ754r yvxFr/0ybbn5RfAmckC821wziERgFwBPUqJGb6giZqxeZXS36JFJryLLeubzXZPmCKUL 96+3dwStSghu1qBqgfz+cOvy53K38evxsNd16gSd1gOy+F290PvDoaBIX0F7QNGM0ktH x6I+q44pCF617/azZlvrOoCvbJAinHGkta0aao73EH4l33eytahjnR3ZnZne9UpZC7/Y mmiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684527897; x=1687119897; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Ip/4xPkpTBx2G+b4cQROiLf32EA1DGXtHtMtqI6ZZUw=; b=X2gBYrTNog1OtVJ4Rpt527A91+NNTBO9auDEghrqmNJpn3p+6TpZwstLZ2HCE5fqob us1j5SgY7rlItegd8pmWGPYfElSbJVYtF+Am7Z5YHzV8H6A60kKMRZDm7lazqYY0mK7u Zv9zKHEtXBTQ8KpYVAbxIoJVMooOX0pFaiTrQncR/YZFL/q+cYpBu1TYPgzvQU979SpT wqH1JWWXGKQOYO4KQx+hvD/PAeuBwVYHG1I3lnGJJnvY9AAZPKFXYOSV6uJnqK+dZYze 8jHDbiIxWieQC4oCI0d0DaokpVtJQbp6VCRixxmDK0/oZRLVcHB5BKqh3qzqipWoCSUR RJxg== X-Gm-Message-State: AC+VfDzskNvDcsxbqAmn/HS0j6dYkyHv+1Dx0HKXjHUROzrJHU9LWNJH gMzsbZ4PKKZ+ydoY31iq2EWfyRCezA== X-Received: by 2002:a5d:4d51:0:b0:2f3:e981:f183 with SMTP id a17-20020a5d4d51000000b002f3e981f183mr2600518wru.10.1684527897243; Fri, 19 May 2023 13:24:57 -0700 (PDT) Received: from p183 ([46.53.249.116]) by smtp.gmail.com with ESMTPSA id l2-20020adfe582000000b0030632833e74sm6314248wrm.11.2023.05.19.13.24.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 May 2023 13:24:56 -0700 (PDT) Date: Fri, 19 May 2023 23:24:54 +0300 From: Alexey Dobriyan <adobriyan@gmail.com> To: akpm@linux-foundation.org Cc: linux-kernel@vger.kernel.org Subject: [PATCH] fix mult_frac() multiple argument evaluation bug Message-ID: <f522ad25-f899-4526-abc4-da35868b6a8b@p183> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1766357521243372837?= X-GMAIL-MSGID: =?utf-8?q?1766357521243372837?= |
Series |
fix mult_frac() multiple argument evaluation bug
|
|
Commit Message
Alexey Dobriyan
May 19, 2023, 8:24 p.m. UTC
mult_frac() evaluates _all_ arguments multiple times in the body.
Clarify comment while I'm at it.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---
include/linux/math.h | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
Comments
On Fri, 19 May 2023 23:24:54 +0300 Alexey Dobriyan <adobriyan@gmail.com> wrote: > mult_frac() evaluates _all_ arguments multiple times in the body. > > --- a/include/linux/math.h > +++ b/include/linux/math.h > @@ -118,17 +118,17 @@ __STRUCT_FRACT(s32) > __STRUCT_FRACT(u32) > #undef __STRUCT_FRACT > > -/* > - * Multiplies an integer by a fraction, while avoiding unnecessary > - * overflow or loss of precision. > - */ > -#define mult_frac(x, numer, denom)( \ > -{ \ > - typeof(x) quot = (x) / (denom); \ > - typeof(x) rem = (x) % (denom); \ > - (quot * (numer)) + ((rem * (numer)) / (denom)); \ > -} \ > -) > +/* Calculate "x * n / d" without unnecessary overflow or loss of precision. */ > +#define mult_frac(x, n, d) \ > +({ \ > + typeof(x) x_ = (x); \ > + typeof(n) n_ = (n); \ > + typeof(d) d_ = (d); \ > + \ > + typeof(x) q = x_ / d_; \ > + typeof(x) r = x_ % d_; \ > + q * n_ + r * n_ / d_; \ > +}) > I like, but the compiler doesn't. x86_64 allmodconfig, gcc-12.2.0. In file included from ./include/linux/math64.h:6, from ./include/linux/time.h:6, from ./include/linux/ktime.h:24, from ./include/linux/timer.h:6, from drivers/target/target_core_iblock.c:16: drivers/target/target_core_iblock.c: In function 'iblock_configure_device': drivers/target/target_core_iblock.c:127:73: error: passing argument 1 of 'queue_max_hw_sectors' makes pointer from integer without a cast [-Werror=int-conversion] 127 | dev->dev_attrib.hw_max_sectors = mult_frac(queue_max_hw_sectors(q), | ^ | | | unsigned int ./include/linux/math.h:129:16: note: in definition of macro 'mult_frac' 129 | typeof(x) r = x_ % d_; \ | ^ In file included from drivers/target/target_core_iblock.c:18: ./include/linux/blkdev.h:1112:77: note: expected 'const struct request_queue *' but argument is of type 'unsigned int' 1112 | static inline unsigned int queue_max_hw_sectors(const struct request_queue *q) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ cc1: all warnings being treated as errors make[3]: *** [scripts/Makefile.build:252: drivers/target/target_core_iblock.o] Error 1 make[3]: *** Waiting for unfinished jobs.... make[2]: *** [scripts/Makefile.build:494: drivers/target] Error 2 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [scripts/Makefile.build:494: drivers] Error 2 make: *** [Makefile:2026: .] Error 2
On Fri, May 19, 2023 at 03:36:22PM -0700, Andrew Morton wrote: > On Fri, 19 May 2023 23:24:54 +0300 Alexey Dobriyan <adobriyan@gmail.com> wrote: > > > mult_frac() evaluates _all_ arguments multiple times in the body. > > > > --- a/include/linux/math.h > > +++ b/include/linux/math.h > > @@ -118,17 +118,17 @@ __STRUCT_FRACT(s32) > > __STRUCT_FRACT(u32) > > #undef __STRUCT_FRACT > > > > -/* > > - * Multiplies an integer by a fraction, while avoiding unnecessary > > - * overflow or loss of precision. > > - */ > > -#define mult_frac(x, numer, denom)( \ > > -{ \ > > - typeof(x) quot = (x) / (denom); \ > > - typeof(x) rem = (x) % (denom); \ > > - (quot * (numer)) + ((rem * (numer)) / (denom)); \ > > -} \ > > -) > > +/* Calculate "x * n / d" without unnecessary overflow or loss of precision. */ > > +#define mult_frac(x, n, d) \ > > +({ \ > > + typeof(x) x_ = (x); \ > > + typeof(n) n_ = (n); \ > > + typeof(d) d_ = (d); \ > > + \ > > + typeof(x) q = x_ / d_; \ > > + typeof(x) r = x_ % d_; \ > > + q * n_ + r * n_ / d_; \ > > +}) > > > > I like, but the compiler doesn't. x86_64 allmodconfig, gcc-12.2.0. > > In file included from ./include/linux/math64.h:6, > from ./include/linux/time.h:6, > from ./include/linux/ktime.h:24, > from ./include/linux/timer.h:6, > from drivers/target/target_core_iblock.c:16: > drivers/target/target_core_iblock.c: In function 'iblock_configure_device': > drivers/target/target_core_iblock.c:127:73: error: passing argument 1 of 'queue_max_hw_sectors' makes pointer from integer without a cast [-Werror=int-conversion] > 127 | dev->dev_attrib.hw_max_sectors = mult_frac(queue_max_hw_sectors(q), > | ^ > | | > | unsigned int > ./include/linux/math.h:129:16: note: in definition of macro 'mult_frac' > 129 | typeof(x) r = x_ % d_; \ > | ^ > In file included from drivers/target/target_core_iblock.c:18: > ./include/linux/blkdev.h:1112:77: note: expected 'const struct request_queue *' but argument is of type 'unsigned int' > 1112 | static inline unsigned int queue_max_hw_sectors(const struct request_queue *q) > | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ In my defence, original macro has the same bug: #define M(a) \ ({ \ typeof(a) b = ...; \ typeof(a) c = ...; \ Now, first typeof can use f(b) because second b doesn't exist yet. But second typeof can not because second b already exists with potentially incompatible type.
--- a/include/linux/math.h +++ b/include/linux/math.h @@ -118,17 +118,17 @@ __STRUCT_FRACT(s32) __STRUCT_FRACT(u32) #undef __STRUCT_FRACT -/* - * Multiplies an integer by a fraction, while avoiding unnecessary - * overflow or loss of precision. - */ -#define mult_frac(x, numer, denom)( \ -{ \ - typeof(x) quot = (x) / (denom); \ - typeof(x) rem = (x) % (denom); \ - (quot * (numer)) + ((rem * (numer)) / (denom)); \ -} \ -) +/* Calculate "x * n / d" without unnecessary overflow or loss of precision. */ +#define mult_frac(x, n, d) \ +({ \ + typeof(x) x_ = (x); \ + typeof(n) n_ = (n); \ + typeof(d) d_ = (d); \ + \ + typeof(x) q = x_ / d_; \ + typeof(x) r = x_ % d_; \ + q * n_ + r * n_ / d_; \ +}) #define sector_div(a, b) do_div(a, b)