Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp5720109pxb; Mon, 28 Mar 2022 16:45:38 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyVb/vYmBg0GnAur3clXyPn9zV9PxU1J2aQJjWNjbH0VQDevpTcXx90jS8AwxB6HtdTuoqR X-Received: by 2002:a63:4405:0:b0:382:173c:1b97 with SMTP id r5-20020a634405000000b00382173c1b97mr11775238pga.532.1648511138247; Mon, 28 Mar 2022 16:45:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648511138; cv=none; d=google.com; s=arc-20160816; b=AvHiZs+JDfKCHlMoO5uvEcPl+pnIzzAnd2NIxA8QeXJkyEFj7Fva0dAL2qRVer9sBF woXfQMAjdzXN9S/DlMKqfH+GyJX5Jx25J0bJtEkDezaMpp1T2PIXZSkaN+mlr9QYhPJ+ yPJmqg35W0aff0yYS8chvrb2AMtv9uHHQ34vK9XrGoRz6JXuBP+kj+lz/Mr2Eo8zNQWr 7QlSHwWxLLU7wyU0QR6IlBYR5tRcuNIe6BHsj2fmNDrkZLCElJqaB06fjAn2rbtTpKrC MpWVw6NGwYkDRr/lofRhSPVYRIe+St+M3KWpTj8Zpaxpqj3YqujRJEM3yzhDwQYsonkn dwTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:user-agent:in-reply-to:content-disposition :mime-version:references:mail-followup-to:reply-to:message-id :subject:cc:to:from:date:dkim-signature:dkim-signature; bh=21Evlhp3V+QRnVu+WtdU3GTS4r6+O5Bat+kErY1IoFc=; b=ELwWXZy5/QUbkmFmk0ju7CQjbPvip01L44jIsCTHfTyFDJ3YYC6SnhQZ8ZLrTDdoJH xbECFRaKKWv+rpR9XU7ybIfWvVOswswGLvbWfL93wTxZRS5a7ZVfvYFrAeTAo/TmOcWV vw288MP+vBj+xBYKfwpjOWCnNBF62tFr4wbkK/A28GE8h0uLOp/UNohZxelEdbHip4of fhhXA8qUuLG99td8RlgUw/KTDnSYc+krLlF3a5vCt35htPwdM8epiu5yDZ43xSN5nOFr 78dQfwNNfFvePV2KdXEOslZmpRZxONO9z32lA6T8+gM4ZY8KBh+gU5H86ISzPx+91BFc Tr7Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.cz header.s=susede2_rsa header.b=l63sl1mN; dkim=neutral (no key) header.i=@suse.cz; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id b4-20020a170903228400b00153b2d1644csi16147198plh.84.2022.03.28.16.45.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Mar 2022 16:45:38 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.cz header.s=susede2_rsa header.b=l63sl1mN; dkim=neutral (no key) header.i=@suse.cz; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 1587B1C13D; Mon, 28 Mar 2022 16:13:24 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230257AbiC1XOx (ORCPT + 99 others); Mon, 28 Mar 2022 19:14:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230288AbiC1XOu (ORCPT ); Mon, 28 Mar 2022 19:14:50 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5FE541C132; Mon, 28 Mar 2022 16:13:08 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id 0119B21C41; Mon, 28 Mar 2022 23:13:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1648509187; h=from:from:reply-to:reply-to:date:date:message-id:message-id:to:to: cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=21Evlhp3V+QRnVu+WtdU3GTS4r6+O5Bat+kErY1IoFc=; b=l63sl1mN3gNS4Kyw+DL2bt7ZNekfe8zUkVXPeB/zKnv1MkFGR+esxO3qknmMHxMdiRUNO+ vBTJC1OtnWv3WXab9m79QOt50+Gj6BfGb0Nd2fUz5iyGGQXHOF9pKvn+FpI2ASXMuP2mQ4 mcNdfhwVge4kzGolodKi4HJiV92ePhI= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1648509187; h=from:from:reply-to:reply-to:date:date:message-id:message-id:to:to: cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=21Evlhp3V+QRnVu+WtdU3GTS4r6+O5Bat+kErY1IoFc=; b=YlCIw+Jyf/h7+iJQmkc8EzlPbUPs3HadNCWe036vB6NR+erPXDWhqW5YV66xmNrGO/x06V kFwQddKEne1KTRBg== Received: from ds.suse.cz (ds.suse.cz [10.100.12.205]) by relay2.suse.de (Postfix) with ESMTP id E9B9CA3B89; Mon, 28 Mar 2022 23:13:06 +0000 (UTC) Received: by ds.suse.cz (Postfix, from userid 10065) id CA6E7DA7F3; Tue, 29 Mar 2022 01:09:09 +0200 (CEST) Date: Tue, 29 Mar 2022 01:09:09 +0200 From: David Sterba To: Sweet Tea Dorminy Cc: Chris Mason , Josef Bacik , David Sterba , Nick Terrell , linux-kernel@vger.kernel.org, linux-btrfs@vger.kernel.org, kernel-team@fb.com Subject: Re: [PATCH 1/2] btrfs: Factor out allocating an array of pages. Message-ID: <20220328230909.GW2237@twin.jikos.cz> Reply-To: dsterba@suse.cz Mail-Followup-To: dsterba@suse.cz, Sweet Tea Dorminy , Chris Mason , Josef Bacik , David Sterba , Nick Terrell , linux-kernel@vger.kernel.org, linux-btrfs@vger.kernel.org, kernel-team@fb.com References: <8a8c3d39c858a1b8610ea967a50c2572c7604f5e.1648497027.git.sweettea-kernel@dorminy.me> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <8a8c3d39c858a1b8610ea967a50c2572c7604f5e.1648497027.git.sweettea-kernel@dorminy.me> User-Agent: Mutt/1.5.23.1-rc1 (2014-03-12) X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no 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: X-Mailing-List: linux-kernel@vger.kernel.org Please format the subjects so there's lower case after "btrfs:" and no "." at the end, I've edited that in your previous patches. On Mon, Mar 28, 2022 at 04:14:27PM -0400, Sweet Tea Dorminy wrote: > Several functions currently populate an array of page pointers one > allocated page at a time; factor out the common code so as to allow > improvements to all of the sites at once. > > Signed-off-by: Sweet Tea Dorminy > --- > fs/btrfs/check-integrity.c | 8 +++----- > fs/btrfs/compression.c | 37 +++++++++++++++-------------------- > fs/btrfs/ctree.c | 25 ++++++++++++++++++++++++ > fs/btrfs/ctree.h | 2 ++ > fs/btrfs/extent_io.c | 40 +++++++++++++++++++++++--------------- > fs/btrfs/inode.c | 10 ++++------ > fs/btrfs/raid56.c | 30 ++++------------------------ > 7 files changed, 78 insertions(+), 74 deletions(-) > > diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c > index 7e9f90fa0388..366d5a80f3c5 100644 > --- a/fs/btrfs/check-integrity.c > +++ b/fs/btrfs/check-integrity.c > @@ -1553,11 +1553,9 @@ static int btrfsic_read_block(struct btrfsic_state *state, > return -ENOMEM; > block_ctx->datav = block_ctx->mem_to_free; > block_ctx->pagev = (struct page **)(block_ctx->datav + num_pages); > - for (i = 0; i < num_pages; i++) { > - block_ctx->pagev[i] = alloc_page(GFP_NOFS); > - if (!block_ctx->pagev[i]) > - return -1; > - } > + ret = btrfs_alloc_page_array(num_pages, block_ctx->pagev); > + if (ret) > + return ret; > > dev_bytenr = block_ctx->dev_bytenr; > for (i = 0; i < num_pages;) { > diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c > index be476f094300..0fc663b757fb 100644 > --- a/fs/btrfs/compression.c > +++ b/fs/btrfs/compression.c > @@ -801,8 +801,6 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, > struct extent_map_tree *em_tree; > struct compressed_bio *cb; > unsigned int compressed_len; > - unsigned int nr_pages; > - unsigned int pg_index; > struct bio *comp_bio = NULL; > const u64 disk_bytenr = bio->bi_iter.bi_sector << SECTOR_SHIFT; > u64 cur_disk_byte = disk_bytenr; > @@ -812,7 +810,8 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, > u64 em_start; > struct extent_map *em; > blk_status_t ret; > - int faili = 0; > + int r; Please don't use single letter variables for basically anything else than an indexing variable 'i', like below. You can use 'ret2' in this case, as is supposed to be the preferred style in btrfs code. > + int i; > u8 *sums; > > em_tree = &BTRFS_I(inode)->extent_tree; > @@ -855,25 +854,20 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, > cb->compress_type = extent_compress_type(bio_flags); > cb->orig_bio = bio; > > - nr_pages = DIV_ROUND_UP(compressed_len, PAGE_SIZE); > - cb->compressed_pages = kcalloc(nr_pages, sizeof(struct page *), > + cb->nr_pages = DIV_ROUND_UP(compressed_len, PAGE_SIZE); > + cb->compressed_pages = kcalloc(cb->nr_pages, sizeof(struct page *), > GFP_NOFS); > if (!cb->compressed_pages) { > ret = BLK_STS_RESOURCE; > - goto fail1; > + goto fail; > } > > - for (pg_index = 0; pg_index < nr_pages; pg_index++) { > - cb->compressed_pages[pg_index] = alloc_page(GFP_NOFS); > - if (!cb->compressed_pages[pg_index]) { > - faili = pg_index - 1; > - ret = BLK_STS_RESOURCE; > - goto fail2; > - } > + r = btrfs_alloc_page_array(cb->nr_pages, cb->compressed_pages); > + if (r) { > + ret = BLK_STS_RESOURCE; > + goto fail; > } > - faili = nr_pages - 1; > - cb->nr_pages = nr_pages; > - > + > add_ra_bio_pages(inode, em_start + em_len, cb); > > /* include any pages we added in add_ra-bio_pages */ > @@ -949,14 +943,15 @@ blk_status_t btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, > } > return BLK_STS_OK; > > -fail2: > - while (faili >= 0) { > - __free_page(cb->compressed_pages[faili]); > - faili--; > +fail: > + if (cb->compressed_pages) { > + for (i = 0; i < cb->nr_pages; i++) { > + if (cb->compressed_pages[i]) > + __free_page(cb->compressed_pages[i]); > + } > } > > kfree(cb->compressed_pages); > -fail1: > kfree(cb); > out: > free_extent_map(em); > diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c > index 1e24695ede0a..4e81e75c8e7c 100644 > --- a/fs/btrfs/ctree.c > +++ b/fs/btrfs/ctree.c > @@ -90,6 +90,31 @@ void btrfs_free_path(struct btrfs_path *p) > kmem_cache_free(btrfs_path_cachep, p); > } > > +/** > + * btrfs_alloc_page_array() - allocate an array of pages. We've been using a simplified format without the function name (as it's right after the comment. > + * > + * @nr_pages: the number of pages to request > + * @page_array: the array to fill with pages. Any existing non-null entries in > + * the array will be skipped. And the argument description should be aligned. > + * > + * Return: 0 if all pages were able to be allocated; -ENOMEM otherwise, and the > + * caller is responsible for freeing all non-null page pointers in the array. > + */ > +int btrfs_alloc_page_array(unsigned long nr_pages, struct page **page_array) > +{ > + int i; Newline > + for (i = 0; i < nr_pages; i++) { > + struct page *page; Newline > + if (page_array[i]) > + continue; > + page = alloc_page(GFP_NOFS); > + if (!page) > + return -ENOMEM; Do you need the return value? For allocation helpers it's just a valid memory or NULL, so you can move the parameter to return value. > + page_array[i] = page; > + } > + return 0; > +} > + > /* > * path release drops references on the extent buffers in the path > * and it drops any locks held by this path > diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h > index 7328fb17b7f5..e835a2bfb60a 100644 > --- a/fs/btrfs/ctree.h > +++ b/fs/btrfs/ctree.h > @@ -2969,6 +2969,8 @@ void btrfs_release_path(struct btrfs_path *p); > struct btrfs_path *btrfs_alloc_path(void); > void btrfs_free_path(struct btrfs_path *p); > > +int btrfs_alloc_page_array(unsigned long nr_pages, struct page **page_array); > + > int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, > struct btrfs_path *path, int slot, int nr); > static inline int btrfs_del_item(struct btrfs_trans_handle *trans, > diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c > index 53b59944013f..c1c8d770f43a 100644 > --- a/fs/btrfs/extent_io.c > +++ b/fs/btrfs/extent_io.c > @@ -5898,9 +5898,9 @@ __alloc_extent_buffer(struct btrfs_fs_info *fs_info, u64 start, > struct extent_buffer *btrfs_clone_extent_buffer(const struct extent_buffer *src) > { > int i; > - struct page *p; > struct extent_buffer *new; > int num_pages = num_extent_pages(src); > + int r; > > new = __alloc_extent_buffer(src->fs_info, src->start, src->len); > if (new == NULL) > @@ -5913,22 +5913,23 @@ struct extent_buffer *btrfs_clone_extent_buffer(const struct extent_buffer *src) > */ > set_bit(EXTENT_BUFFER_UNMAPPED, &new->bflags); > > + memset(new->pages, 0, sizeof(*new->pages) * num_pages); > + r = btrfs_alloc_page_array(num_pages, new->pages); > + if (r) { > + btrfs_release_extent_buffer(new); > + return NULL; > + } > + > for (i = 0; i < num_pages; i++) { > int ret; > + struct page *p = new->pages[i]; > > - p = alloc_page(GFP_NOFS); > - if (!p) { > - btrfs_release_extent_buffer(new); > - return NULL; > - } > ret = attach_extent_buffer_page(new, p, NULL); > if (ret < 0) { > - put_page(p); > btrfs_release_extent_buffer(new); > return NULL; > } > WARN_ON(PageDirty(p)); > - new->pages[i] = p; > copy_page(page_address(p), page_address(src->pages[i])); > } > set_extent_buffer_uptodate(new); > @@ -5942,31 +5943,38 @@ struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, > struct extent_buffer *eb; > int num_pages; > int i; > + int r; > > eb = __alloc_extent_buffer(fs_info, start, len); > if (!eb) > return NULL; > > num_pages = num_extent_pages(eb); > + r = btrfs_alloc_page_array(num_pages, eb->pages); > + if (r) > + goto err; > + > for (i = 0; i < num_pages; i++) { > int ret; > + struct page *p = eb->pages[i]; > > - eb->pages[i] = alloc_page(GFP_NOFS); > - if (!eb->pages[i]) > - goto err; > - ret = attach_extent_buffer_page(eb, eb->pages[i], NULL); > - if (ret < 0) > + ret = attach_extent_buffer_page(eb, p, NULL); > + if (ret < 0) { > goto err; > + } No { } around single statements. > } > + > set_extent_buffer_uptodate(eb); > btrfs_set_header_nritems(eb, 0); > set_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags); > > return eb; > err: > - for (; i > 0; i--) { > - detach_extent_buffer_page(eb, eb->pages[i - 1]); > - __free_page(eb->pages[i - 1]); > + for (i = 0; i < num_pages; i++) { > + if (eb->pages[i]) { > + detach_extent_buffer_page(eb, eb->pages[i]); > + __free_page(eb->pages[i]); > + } > } > __free_extent_buffer(eb); > return NULL; > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index c7b15634fe70..121858652a09 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -10427,13 +10427,11 @@ static ssize_t btrfs_encoded_read_regular(struct kiocb *iocb, > pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); > if (!pages) > return -ENOMEM; > - for (i = 0; i < nr_pages; i++) { > - pages[i] = alloc_page(GFP_NOFS); > - if (!pages[i]) { > - ret = -ENOMEM; > - goto out; > + ret = btrfs_alloc_page_array(nr_pages, pages); > + if (ret) { > + ret = -ENOMEM; > + goto out; > } > - } > > ret = btrfs_encoded_read_regular_fill_pages(inode, start, disk_bytenr, > disk_io_size, pages); > diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c > index 0e239a4c3b26..ea7a9152b1cc 100644 > --- a/fs/btrfs/raid56.c > +++ b/fs/btrfs/raid56.c > @@ -1026,37 +1026,15 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info, > /* allocate pages for all the stripes in the bio, including parity */ > static int alloc_rbio_pages(struct btrfs_raid_bio *rbio) > { > - int i; > - struct page *page; > - > - for (i = 0; i < rbio->nr_pages; i++) { > - if (rbio->stripe_pages[i]) > - continue; > - page = alloc_page(GFP_NOFS); > - if (!page) > - return -ENOMEM; > - rbio->stripe_pages[i] = page; > - } > - return 0; > + return btrfs_alloc_page_array(rbio->nr_pages, rbio->stripe_pages); > } > > /* only allocate pages for p/q stripes */ > static int alloc_rbio_parity_pages(struct btrfs_raid_bio *rbio) > { > - int i; > - struct page *page; > - > - i = rbio_stripe_page_index(rbio, rbio->nr_data, 0); > - > - for (; i < rbio->nr_pages; i++) { > - if (rbio->stripe_pages[i]) > - continue; > - page = alloc_page(GFP_NOFS); > - if (!page) > - return -ENOMEM; > - rbio->stripe_pages[i] = page; > - } > - return 0; > + int data_pages = rbio_stripe_page_index(rbio, rbio->nr_data, 0); > + return btrfs_alloc_page_array(rbio->nr_pages - data_pages, > + rbio->stripe_pages + data_pages); > } > > /* > -- > 2.35.1