Message ID | 2e6a82a83d0ddd9ce7f36ea889dd7ffc30f5fbc9.1694853900.git.christophe.jaillet@wanadoo.fr |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp1629298vqi; Sat, 16 Sep 2023 05:23:07 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGOW9SwnHfV956taTXbUBbLFQ46OzKFo79zOYwYgzWgUWDJyiYGrvF5Gnqw8VYNPXzEN243 X-Received: by 2002:a05:6a20:42a7:b0:12d:ba1e:d763 with SMTP id o39-20020a056a2042a700b0012dba1ed763mr4930409pzj.7.1694866987359; Sat, 16 Sep 2023 05:23:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694866987; cv=none; d=google.com; s=arc-20160816; b=oGg8rjlyIyf96eJN2FhoqGBk1VttWYgAScXObehrsNl9URNQ7nQ9/IZ9/xJR3nqA4Y 4Q8YSyAM0ulJJ2hHAU7wRyOtG6JWu0JHjJWIg82ByYxP6nFlbA++DH2boLfl86D5zFDM rEWsAIzicdk1BLULi8BMlYO3QqnLu1UhjG2krvLaYzbsrfSx4DT4sUAAX3lNxFVnNzoP Wu6FvAqmDteARuXap4FZLgU3gt3n/99b0RTlPOZ7LMB1Bi7GGvTsvh82Ity/kWSVMF0g BNhJiw1QLcrdVjWBcI39ncbo1rx61H7r3IMuyytlob5l/Pmy+w+9aQ2qUKpk06G7mB3u fl6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=cA7WgRDiydPCuNf/SfhbEh7C8ImUKHG5ugsQxiw8lwY=; fh=m3UyueLH4KDy0H9ZPaSnoQRYWYiD76Xl1Jq/Gorb8Ss=; b=g+ZydQB0mRAQWnahJFA/VRAMcT3HrsXlEt48iPDgkSKKfi1DLRUKkHFMCZ/Mc7mFX8 w62RqXmRQByVnBlfkM0bxvEHAlVXvtSWgzM0bvQ2hAfKKDajluhCvGPtWU9aUXizVgC6 M/IPhVe2sArUdNPjporw4cMxEqBJPx1N8X2euGEfIP/b79joxLJFiDPtnhbB1/xNhj4j rWHRiBGmdTPkS9S0gHdLkBrcH3M2grcx59x85K1nc2b96uGcMotnxIMzd8YYeW+0vY0X iUu53plR268XUhsjvgzbkCzvzWaBXGdLIt9JL5Kj1qBw2gkbNKYKyBrWLzJ+nLGFIhIy ggjg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@wanadoo.fr header.s=t20230301 header.b=PXR0QG3l; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=wanadoo.fr Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id z10-20020aa7888a000000b0068fba36099dsi5062547pfe.386.2023.09.16.05.23.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 Sep 2023 05:23:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@wanadoo.fr header.s=t20230301 header.b=PXR0QG3l; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=wanadoo.fr Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 15534836B0DC; Sat, 16 Sep 2023 01:50:00 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230215AbjIPIpo (ORCPT <rfc822;toshivichauhan@gmail.com> + 27 others); Sat, 16 Sep 2023 04:45:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229866AbjIPIpe (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 16 Sep 2023 04:45:34 -0400 Received: from smtp.smtpout.orange.fr (smtp-27.smtpout.orange.fr [80.12.242.27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A774E6A for <linux-kernel@vger.kernel.org>; Sat, 16 Sep 2023 01:45:28 -0700 (PDT) Received: from pop-os.home ([86.243.2.178]) by smtp.orange.fr with ESMTPA id hQvcqqzCHBh1whQvdqxVHj; Sat, 16 Sep 2023 10:45:26 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wanadoo.fr; s=t20230301; t=1694853926; bh=cA7WgRDiydPCuNf/SfhbEh7C8ImUKHG5ugsQxiw8lwY=; h=From:To:Cc:Subject:Date; b=PXR0QG3lTF7N9XgySHtDSVHe2gdPAui/WnZoRa2jD4u6bFFju0FxGWZXXpgOZ1Zub KaQs4MkZCze4W+AMVDuwKYr8+oaTF6byXp83/WAYzoRA7GEmubQr/z9h8XQRMwjXWM fjsxpRFwwwIwS2+9X0J2TCLn7jaeTuWD6s/P92SYMiBYo3C5UIu6gZctUDQpTC5GC7 U+E0x0M+VWXIphkCqGJq0xN92+f7T61PVW7QbcGpbAVX2jlrOajoTJ85Slb9rkos/6 uhyGVLXfiA8veXc5cyAJI0m/+LI7VNsa4fkaaGCwPNFc2YT45zm+pcgSPs/R6DTD15 4VJ86sWwTPdUQ== X-ME-Helo: pop-os.home X-ME-Auth: Y2hyaXN0b3BoZS5qYWlsbGV0QHdhbmFkb28uZnI= X-ME-Date: Sat, 16 Sep 2023 10:45:26 +0200 X-ME-IP: 86.243.2.178 From: Christophe JAILLET <christophe.jaillet@wanadoo.fr> To: Kent Overstreet <kent.overstreet@linux.dev>, Brian Foster <bfoster@redhat.com> Cc: linux-kernel@vger.kernel.org, kernel-janitors@vger.kernel.org, Christophe JAILLET <christophe.jaillet@wanadoo.fr>, linux-bcachefs@vger.kernel.org Subject: [PATCH] bcachefs: Avoid a potential memory over-allocation in bch2_printbuf_make_room() Date: Sat, 16 Sep 2023 10:45:23 +0200 Message-Id: <2e6a82a83d0ddd9ce7f36ea889dd7ffc30f5fbc9.1694853900.git.christophe.jaillet@wanadoo.fr> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS 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-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Sat, 16 Sep 2023 01:50:00 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777196845908108389 X-GMAIL-MSGID: 1777196845908108389 |
Series |
bcachefs: Avoid a potential memory over-allocation in bch2_printbuf_make_room()
|
|
Commit Message
Christophe JAILLET
Sept. 16, 2023, 8:45 a.m. UTC
kmalloc() and co. don't always allocate a power of 2 number of bytes.
There are some special handling for 64<n<=96 and 128<n<=192 cases.
So trust kmalloc() algorithm instead of forcing a power of 2 allocation.
This can saves a few bytes of memory and still make use of all the
memory allocated.
On the other side, it may require an additional realloc() in some cases.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
fs/bcachefs/printbuf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Comments
On Sat, Sep 16, 2023 at 10:45:23AM +0200, Christophe JAILLET wrote: > kmalloc() and co. don't always allocate a power of 2 number of bytes. > There are some special handling for 64<n<=96 and 128<n<=192 cases. > It's not immediately clear to me what you mean by "special handling." Taking a quick look at slabinfo, it looks like what you mean is that slab rounding is a bit more granular than power of two, particularly in these ranges. Is that right? If so, JFYI it would be helpful to describe that more explicitly in the commit log. > So trust kmalloc() algorithm instead of forcing a power of 2 allocation. > This can saves a few bytes of memory and still make use of all the > memory allocated. > > On the other side, it may require an additional realloc() in some cases. > Well, I feel like this isn't the only place I've seen the power of two buffer size realloc algorithm thing, but in thinking about it this seems fairly harmless and reasonable for printbufs. FWIW: Reviewed-by: Brian Foster <bfoster@redhat.com> > Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> > --- > fs/bcachefs/printbuf.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/bcachefs/printbuf.c b/fs/bcachefs/printbuf.c > index 77bee9060bfe..34527407e950 100644 > --- a/fs/bcachefs/printbuf.c > +++ b/fs/bcachefs/printbuf.c > @@ -28,7 +28,7 @@ int bch2_printbuf_make_room(struct printbuf *out, unsigned extra) > if (out->pos + extra < out->size) > return 0; > > - new_size = roundup_pow_of_two(out->size + extra); > + new_size = kmalloc_size_roundup(out->size + extra); > > /* > * Note: output buffer must be freeable with kfree(), it's not required > -- > 2.34.1 >
Le 19/09/2023 à 15:18, Brian Foster a écrit : > On Sat, Sep 16, 2023 at 10:45:23AM +0200, Christophe JAILLET wrote: >> kmalloc() and co. don't always allocate a power of 2 number of bytes. >> There are some special handling for 64<n<=96 and 128<n<=192 cases. >> > > It's not immediately clear to me what you mean by "special handling." > Taking a quick look at slabinfo, it looks like what you mean is that > slab rounding is a bit more granular than power of two, particularly in > these ranges. Is that right? If so, JFYI it would be helpful to describe > that more explicitly in the commit log. That's what I tried to do with my 2 phrases. Sound good and clear to the French speaking man I am :) Would you mind updating the phrasing yourself? A trial and error method about wording with a non native English speaking person can be somewhat a long and boring experience to me. All what I could propose, with the help of google translate, is: " kmalloc() does not necessarily allocate a number of bytes equal to a power of two. There are special cases for sizes between 65 and 96 and between 129 and 192. In these cases, 96 and 192 bytes are allocated respectively. So, instead of forcing an allocation always equal to a power of two, it may be interesting to use the same rounding rules as kmalloc(). This helps avoid over-allocating some memory. Use kmalloc_size_roundup() instead of roundup_pow_of_two(). " If this is fine to you I can send a v2 with this wording, otherwise, either tweak it to what sounds good to you, or just ignore this patch. CJ > >> So trust kmalloc() algorithm instead of forcing a power of 2 allocation. >> This can saves a few bytes of memory and still make use of all the >> memory allocated. >> >> On the other side, it may require an additional realloc() in some cases. >> > > Well, I feel like this isn't the only place I've seen the power of two > buffer size realloc algorithm thing, but in thinking about it this seems > fairly harmless and reasonable for printbufs. FWIW: > > Reviewed-by: Brian Foster <bfoster@redhat.com> > >> Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> >> --- >> fs/bcachefs/printbuf.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/fs/bcachefs/printbuf.c b/fs/bcachefs/printbuf.c >> index 77bee9060bfe..34527407e950 100644 >> --- a/fs/bcachefs/printbuf.c >> +++ b/fs/bcachefs/printbuf.c >> @@ -28,7 +28,7 @@ int bch2_printbuf_make_room(struct printbuf *out, unsigned extra) >> if (out->pos + extra < out->size) >> return 0; >> >> - new_size = roundup_pow_of_two(out->size + extra); >> + new_size = kmalloc_size_roundup(out->size + extra); >> >> /* >> * Note: output buffer must be freeable with kfree(), it's not required >> -- >> 2.34.1 >> > >
On Tue, Sep 19, 2023 at 08:34:00PM +0200, Christophe JAILLET wrote: > Le 19/09/2023 à 15:18, Brian Foster a écrit : > > On Sat, Sep 16, 2023 at 10:45:23AM +0200, Christophe JAILLET wrote: > > > kmalloc() and co. don't always allocate a power of 2 number of bytes. > > > There are some special handling for 64<n<=96 and 128<n<=192 cases. > > > > > > > It's not immediately clear to me what you mean by "special handling." > > Taking a quick look at slabinfo, it looks like what you mean is that > > slab rounding is a bit more granular than power of two, particularly in > > these ranges. Is that right? If so, JFYI it would be helpful to describe > > that more explicitly in the commit log. > > That's what I tried to do with my 2 phrases. > Sound good and clear to the French speaking man I am :) > > Would you mind updating the phrasing yourself? > A trial and error method about wording with a non native English speaking > person can be somewhat a long and boring experience to me. > > All what I could propose, with the help of google translate, is: > > " > kmalloc() does not necessarily allocate a number of bytes equal to a power > of two. There are special cases for sizes between 65 and 96 and between 129 > and 192. In these cases, 96 and 192 bytes are allocated respectively. > > So, instead of forcing an allocation always equal to a power of two, it may > be interesting to use the same rounding rules as kmalloc(). This helps avoid > over-allocating some memory. > > Use kmalloc_size_roundup() instead of roundup_pow_of_two(). > " > > If this is fine to you I can send a v2 with this wording, otherwise, either > tweak it to what sounds good to you, or just ignore this patch. > I think that wording is fine. I don't think it's necessary to send a v2 just for a commit log update, but feel free to do so if you want. Ultimately it will be up to Kent if he's alright with the change. Brian > CJ > > > > > > So trust kmalloc() algorithm instead of forcing a power of 2 allocation. > > > This can saves a few bytes of memory and still make use of all the > > > memory allocated. > > > > > > On the other side, it may require an additional realloc() in some cases. > > > > > > > Well, I feel like this isn't the only place I've seen the power of two > > buffer size realloc algorithm thing, but in thinking about it this seems > > fairly harmless and reasonable for printbufs. FWIW: > > > > Reviewed-by: Brian Foster <bfoster@redhat.com> > > > > > Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> > > > --- > > > fs/bcachefs/printbuf.c | 2 +- > > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > > > diff --git a/fs/bcachefs/printbuf.c b/fs/bcachefs/printbuf.c > > > index 77bee9060bfe..34527407e950 100644 > > > --- a/fs/bcachefs/printbuf.c > > > +++ b/fs/bcachefs/printbuf.c > > > @@ -28,7 +28,7 @@ int bch2_printbuf_make_room(struct printbuf *out, unsigned extra) > > > if (out->pos + extra < out->size) > > > return 0; > > > - new_size = roundup_pow_of_two(out->size + extra); > > > + new_size = kmalloc_size_roundup(out->size + extra); > > > /* > > > * Note: output buffer must be freeable with kfree(), it's not required > > > -- > > > 2.34.1 > > > > > > > >
On Tue, Sep 19, 2023 at 08:34:00PM +0200, Christophe JAILLET wrote: > Le 19/09/2023 à 15:18, Brian Foster a écrit : > > On Sat, Sep 16, 2023 at 10:45:23AM +0200, Christophe JAILLET wrote: > > > kmalloc() and co. don't always allocate a power of 2 number of bytes. > > > There are some special handling for 64<n<=96 and 128<n<=192 cases. > > > > > > > It's not immediately clear to me what you mean by "special handling." > > Taking a quick look at slabinfo, it looks like what you mean is that > > slab rounding is a bit more granular than power of two, particularly in > > these ranges. Is that right? If so, JFYI it would be helpful to describe > > that more explicitly in the commit log. > > That's what I tried to do with my 2 phrases. > Sound good and clear to the French speaking man I am :) > > Would you mind updating the phrasing yourself? > A trial and error method about wording with a non native English speaking > person can be somewhat a long and boring experience to me. > > All what I could propose, with the help of google translate, is: > > " > kmalloc() does not necessarily allocate a number of bytes equal to a power > of two. There are special cases for sizes between 65 and 96 and between 129 > and 192. In these cases, 96 and 192 bytes are allocated respectively. > > So, instead of forcing an allocation always equal to a power of two, it may > be interesting to use the same rounding rules as kmalloc(). This helps avoid > over-allocating some memory. > > Use kmalloc_size_roundup() instead of roundup_pow_of_two(). kmalloc_size_roundup() actually isn't correct in this situation. Whenever doing a dynamically growable array (e.g. a vector), when reallocating the new size has to be a constant factor multiple of the old size. This gets you amortized constant time for vector insertion; growing the array differently can easily get you O(n^2) time. IOW, avoiding internal fragmentation isn't what we want; internal fragmentation is already bounded by the current code.
diff --git a/fs/bcachefs/printbuf.c b/fs/bcachefs/printbuf.c index 77bee9060bfe..34527407e950 100644 --- a/fs/bcachefs/printbuf.c +++ b/fs/bcachefs/printbuf.c @@ -28,7 +28,7 @@ int bch2_printbuf_make_room(struct printbuf *out, unsigned extra) if (out->pos + extra < out->size) return 0; - new_size = roundup_pow_of_two(out->size + extra); + new_size = kmalloc_size_roundup(out->size + extra); /* * Note: output buffer must be freeable with kfree(), it's not required