From patchwork Tue Jun 20 21:32:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 13286460 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFD0FEB64D8 for ; Tue, 20 Jun 2023 21:32:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229538AbjFTVc2 (ORCPT ); Tue, 20 Jun 2023 17:32:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52486 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230173AbjFTVc1 (ORCPT ); Tue, 20 Jun 2023 17:32:27 -0400 Received: from mail-pg1-x52a.google.com (mail-pg1-x52a.google.com [IPv6:2607:f8b0:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 316C7170D for ; Tue, 20 Jun 2023 14:32:24 -0700 (PDT) Received: by mail-pg1-x52a.google.com with SMTP id 41be03b00d2f7-54f75f85a17so2777687a12.0 for ; Tue, 20 Jun 2023 14:32:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20221208.gappssmtp.com; s=20221208; t=1687296743; x=1689888743; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UmRPyLfBt9DWl3eoPuPkEqyGs8muqdG95XqIxc2t7qU=; b=g+BgUeLGWj+TRqtF7YxYhd+lKuWEcIH4Rq3jBV2KTESmDZC8zfDryI+RxZeuzxbeNV t1XI7e2wJhHoGUkublH4G6RuCw6VCqQbrjCQVYKt9kUlGyfW60VWB9f5CFocf3OjnMGO Odw5WKiwbpMPrt5N/bogN7UPUTWgZPWI0sq7n2OHjQ5RV02fhLrm9ID5z0cm5rkeMFcX muJVfFTgwxuas6NQKyDUw8HowLMdCy1HbD0n2naTup1zA48Kk/6JkDpRGJjI2VLSI8Kl vlEVP1lSB1S1THXBAHHKtQsLhpHtgACK3anFHMe2mNz/+uefSDs7iQcyo/XL+Ras26Kc PYnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687296743; x=1689888743; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UmRPyLfBt9DWl3eoPuPkEqyGs8muqdG95XqIxc2t7qU=; b=LJrP3Wlab3tm5D0gtgliyqhrO46d0Pq2CigspjMuUWBTYpXtbeCDSr8h2GpszTEECl Qm8bU3ZUI8wYavBuujP+rFnxKpV+oC5MVHYMUTOLyeGzBCT6vWyolr+bWyKr1IgNtKhf 6sUoT2hfZRRycS14TvTjkQQNeNqvt0KNWtadXmkq45AgjfQucYi7vAD26+rd4PCihEGH 5+NBbWQwIhKI7KU0GIwa7OG5CmRYe3jDtKQCee+czWx/7Kq1YDcb632OuJzba2aRM+Y5 rlrnn+H12yGfZEprE4qlHZyithjev/lOL1s9v/M9gQ7jNIBQJmuffPOgICghuH3EjhPB qnWA== X-Gm-Message-State: AC+VfDyCIjCXc6qLDNfLxv1UmtM6oECyIxjSKetQLmqQHGmTOXmnF/6a R33FpUsBANksWEHXy6b45sm2L7035cpsxC+CKPc= X-Google-Smtp-Source: ACHHUZ6pnj+WbDoYBMVBLownyh/zDjSBIFptdrvORusj7BCKrf5lbR2NdOdS16eyUOHBGc09TtOfIg== X-Received: by 2002:a05:6a21:3005:b0:11d:1f5a:d708 with SMTP id yd5-20020a056a21300500b0011d1f5ad708mr7406906pzb.33.1687296742610; Tue, 20 Jun 2023 14:32:22 -0700 (PDT) Received: from telecaster.hsd1.wa.comcast.net ([2620:10d:c090:400::5:ea8e]) by smtp.gmail.com with ESMTPSA id 5-20020aa79205000000b0064d3a9def35sm1688188pfo.188.2023.06.20.14.32.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jun 2023 14:32:22 -0700 (PDT) From: Omar Sandoval To: linux-xfs@vger.kernel.org Cc: "Darrick J . Wong" , kernel-team@fb.com, Prashant Nema Subject: [PATCH 1/6] xfs: cache last bitmap block in realtime allocator Date: Tue, 20 Jun 2023 14:32:11 -0700 Message-ID: <32d2288968c76dc51b2e735e557138925aa09e60.1687296675.git.osandov@osandov.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Omar Sandoval Profiling a workload on a highly fragmented realtime device showed a ton of CPU cycles being spent in xfs_trans_read_buf() called by xfs_rtbuf_get(). Further tracing showed that much of that was repeated calls to xfs_rtbuf_get() for the same block of the realtime bitmap. These come from xfs_rtallocate_extent_block(): as it walks through ranges of free bits in the bitmap, each call to xfs_rtcheck_range() and xfs_rtfind_{forw,back}() gets the same bitmap block. If the bitmap block is very fragmented, then this is _a lot_ of buffer lookups. The realtime allocator already passes around a cache of the last used realtime summary block to avoid repeated reads (the parameters rbpp and rsb). We can do the same for the realtime bitmap. This replaces rbpp and rsb with a struct xfs_rtbuf_cache, which caches the most recently used block for both the realtime bitmap and summary. xfs_rtbuf_get() now handles the caching instead of the callers, which requires plumbing xfs_rtbuf_cache to more functions but also makes sure we don't miss anything. Signed-off-by: Omar Sandoval --- fs/xfs/libxfs/xfs_rtbitmap.c | 167 ++++++++++++++++++----------------- fs/xfs/xfs_rtalloc.c | 107 ++++++++++------------ fs/xfs/xfs_rtalloc.h | 28 ++++-- 3 files changed, 154 insertions(+), 148 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index fa180ab66b73..1a832c9a412f 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -46,6 +46,21 @@ const struct xfs_buf_ops xfs_rtbuf_ops = { .verify_write = xfs_rtbuf_verify_write, }; +static void +xfs_rtbuf_cache_relse( + xfs_trans_t *tp, /* transaction pointer */ + struct xfs_rtbuf_cache *cache) /* cached blocks */ +{ + if (cache->bbuf) { + xfs_trans_brelse(tp, cache->bbuf); + cache->bbuf = NULL; + } + if (cache->sbuf) { + xfs_trans_brelse(tp, cache->sbuf); + cache->sbuf = NULL; + } +} + /* * Get a buffer for the bitmap or summary file block specified. * The buffer is returned read and locked. @@ -56,14 +71,35 @@ xfs_rtbuf_get( xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t block, /* block number in bitmap or summary */ int issum, /* is summary not bitmap */ + struct xfs_rtbuf_cache *cache, /* in/out: cached blocks */ struct xfs_buf **bpp) /* output: buffer for the block */ { + struct xfs_buf **cbpp; /* cached block buffer */ + xfs_fsblock_t *cbp; /* cached block number */ struct xfs_buf *bp; /* block buffer, result */ xfs_inode_t *ip; /* bitmap or summary inode */ xfs_bmbt_irec_t map; int nmap = 1; int error; /* error value */ + cbpp = issum ? &cache->bbuf : &cache->sbuf; + cbp = issum ? &cache->bblock : &cache->sblock; + /* + * If we have a cached buffer, and the block number matches, use that. + */ + if (*cbpp && *cbp == block) { + *bpp = *cbpp; + return 0; + } + /* + * Otherwise we have to have to get the buffer. If there was an old + * one, get rid of it first. + */ + if (*cbpp) { + xfs_trans_brelse(tp, *cbpp); + *cbpp = NULL; + } + ip = issum ? mp->m_rsumip : mp->m_rbmip; error = xfs_bmapi_read(ip, block, 1, &map, &nmap, 0); @@ -82,7 +118,8 @@ xfs_rtbuf_get( xfs_trans_buf_set_type(tp, bp, issum ? XFS_BLFT_RTSUMMARY_BUF : XFS_BLFT_RTBITMAP_BUF); - *bpp = bp; + *cbpp = *bpp = bp; + *cbp = block; return 0; } @@ -96,6 +133,7 @@ xfs_rtfind_back( xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to look at */ xfs_rtblock_t limit, /* last block to look at */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ xfs_rtblock_t *rtblock) /* out: start block found */ { xfs_rtword_t *b; /* current word in buffer */ @@ -116,7 +154,7 @@ xfs_rtfind_back( * Compute and read in starting bitmap block for starting block. */ block = XFS_BITTOBLOCK(mp, start); - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, block, 0, rtbufc, &bp); if (error) { return error; } @@ -153,7 +191,6 @@ xfs_rtfind_back( /* * Different. Mark where we are and return. */ - xfs_trans_brelse(tp, bp); i = bit - XFS_RTHIBIT(wdiff); *rtblock = start - i + 1; return 0; @@ -167,8 +204,7 @@ xfs_rtfind_back( /* * If done with this block, get the previous one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, --block, 0, rtbufc, &bp); if (error) { return error; } @@ -199,7 +235,6 @@ xfs_rtfind_back( /* * Different, mark where we are and return. */ - xfs_trans_brelse(tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); *rtblock = start - i + 1; return 0; @@ -213,8 +248,7 @@ xfs_rtfind_back( /* * If done with this block, get the previous one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, --block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, --block, 0, rtbufc, &bp); if (error) { return error; } @@ -246,7 +280,6 @@ xfs_rtfind_back( /* * Different, mark where we are and return. */ - xfs_trans_brelse(tp, bp); i += XFS_NBWORD - 1 - XFS_RTHIBIT(wdiff); *rtblock = start - i + 1; return 0; @@ -256,7 +289,6 @@ xfs_rtfind_back( /* * No match, return that we scanned the whole area. */ - xfs_trans_brelse(tp, bp); *rtblock = start - i + 1; return 0; } @@ -271,6 +303,7 @@ xfs_rtfind_forw( xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to look at */ xfs_rtblock_t limit, /* last block to look at */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ xfs_rtblock_t *rtblock) /* out: start block found */ { xfs_rtword_t *b; /* current word in buffer */ @@ -291,7 +324,7 @@ xfs_rtfind_forw( * Compute and read in starting bitmap block for starting block. */ block = XFS_BITTOBLOCK(mp, start); - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, block, 0, rtbufc, &bp); if (error) { return error; } @@ -327,7 +360,6 @@ xfs_rtfind_forw( /* * Different. Mark where we are and return. */ - xfs_trans_brelse(tp, bp); i = XFS_RTLOBIT(wdiff) - bit; *rtblock = start + i - 1; return 0; @@ -341,8 +373,7 @@ xfs_rtfind_forw( /* * If done with this block, get the previous one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, rtbufc, &bp); if (error) { return error; } @@ -372,7 +403,6 @@ xfs_rtfind_forw( /* * Different, mark where we are and return. */ - xfs_trans_brelse(tp, bp); i += XFS_RTLOBIT(wdiff); *rtblock = start + i - 1; return 0; @@ -386,8 +416,7 @@ xfs_rtfind_forw( /* * If done with this block, get the next one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, rtbufc, &bp); if (error) { return error; } @@ -416,7 +445,6 @@ xfs_rtfind_forw( /* * Different, mark where we are and return. */ - xfs_trans_brelse(tp, bp); i += XFS_RTLOBIT(wdiff); *rtblock = start + i - 1; return 0; @@ -426,7 +454,6 @@ xfs_rtfind_forw( /* * No match, return that we scanned the whole area. */ - xfs_trans_brelse(tp, bp); *rtblock = start + i - 1; return 0; } @@ -447,8 +474,7 @@ xfs_rtmodify_summary_int( int log, /* log2 of extent size */ xfs_rtblock_t bbno, /* bitmap block number */ int delta, /* change to make to summary info */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ xfs_suminfo_t *sum) /* out: summary info for this block */ { struct xfs_buf *bp; /* buffer for the summary block */ @@ -465,30 +491,9 @@ xfs_rtmodify_summary_int( * Compute the block number in the summary file. */ sb = XFS_SUMOFFSTOBLOCK(mp, so); - /* - * If we have an old buffer, and the block number matches, use that. - */ - if (*rbpp && *rsb == sb) - bp = *rbpp; - /* - * Otherwise we have to get the buffer. - */ - else { - /* - * If there was an old one, get rid of it first. - */ - if (*rbpp) - xfs_trans_brelse(tp, *rbpp); - error = xfs_rtbuf_get(mp, tp, sb, 1, &bp); - if (error) { - return error; - } - /* - * Remember this buffer and block for the next call. - */ - *rbpp = bp; - *rsb = sb; - } + error = xfs_rtbuf_get(mp, tp, sb, 1, rtbufc, &bp); + if (error) + return error; /* * Point to the summary information, modify/log it, and/or copy it out. */ @@ -517,11 +522,9 @@ xfs_rtmodify_summary( int log, /* log2 of extent size */ xfs_rtblock_t bbno, /* bitmap block number */ int delta, /* change to make to summary info */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb) /* in/out: summary block number */ + struct xfs_rtbuf_cache *rtbufc) /* in/out: cache of realtime blocks */ { - return xfs_rtmodify_summary_int(mp, tp, log, bbno, - delta, rbpp, rsb, NULL); + return xfs_rtmodify_summary_int(mp, tp, log, bbno, delta, rtbufc, NULL); } /* @@ -534,7 +537,8 @@ xfs_rtmodify_range( xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to modify */ xfs_extlen_t len, /* length of extent to modify */ - int val) /* 1 for free, 0 for allocated */ + int val, /* 1 for free, 0 for allocated */ + struct xfs_rtbuf_cache *rtbufc) /* in/out: cache of realtime blocks */ { xfs_rtword_t *b; /* current word in buffer */ int bit; /* bit number in the word */ @@ -555,7 +559,7 @@ xfs_rtmodify_range( /* * Read the bitmap block, and point to its data. */ - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, block, 0, rtbufc, &bp); if (error) { return error; } @@ -600,7 +604,7 @@ xfs_rtmodify_range( xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), (uint)((char *)b - (char *)bufp)); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, rtbufc, &bp); if (error) { return error; } @@ -640,7 +644,7 @@ xfs_rtmodify_range( xfs_trans_log_buf(tp, bp, (uint)((char *)first - (char *)bufp), (uint)((char *)b - (char *)bufp)); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, rtbufc, &bp); if (error) { return error; } @@ -690,8 +694,7 @@ xfs_rtfree_range( xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* starting block to free */ xfs_extlen_t len, /* length to free */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb) /* in/out: summary block number */ + struct xfs_rtbuf_cache *rtbufc) /* in/out: cache of realtime blocks */ { xfs_rtblock_t end; /* end of the freed extent */ int error; /* error value */ @@ -702,7 +705,7 @@ xfs_rtfree_range( /* * Modify the bitmap to mark this extent freed. */ - error = xfs_rtmodify_range(mp, tp, start, len, 1); + error = xfs_rtmodify_range(mp, tp, start, len, 1, rtbufc); if (error) { return error; } @@ -711,7 +714,7 @@ xfs_rtfree_range( * We need to find the beginning and end of the extent so we can * properly update the summary. */ - error = xfs_rtfind_back(mp, tp, start, 0, &preblock); + error = xfs_rtfind_back(mp, tp, start, 0, rtbufc, &preblock); if (error) { return error; } @@ -719,7 +722,7 @@ xfs_rtfree_range( * Find the next allocated block (end of allocated extent). */ error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, - &postblock); + rtbufc, &postblock); if (error) return error; /* @@ -729,7 +732,7 @@ xfs_rtfree_range( if (preblock < start) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(start - preblock), - XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); + XFS_BITTOBLOCK(mp, preblock), -1, rtbufc); if (error) { return error; } @@ -741,7 +744,7 @@ xfs_rtfree_range( if (postblock > end) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock - end), - XFS_BITTOBLOCK(mp, end + 1), -1, rbpp, rsb); + XFS_BITTOBLOCK(mp, end + 1), -1, rtbufc); if (error) { return error; } @@ -752,7 +755,7 @@ xfs_rtfree_range( */ error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock + 1 - preblock), - XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); + XFS_BITTOBLOCK(mp, preblock), 1, rtbufc); return error; } @@ -767,6 +770,7 @@ xfs_rtcheck_range( xfs_rtblock_t start, /* starting block number of extent */ xfs_extlen_t len, /* length of extent */ int val, /* 1 for free, 0 for allocated */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ xfs_rtblock_t *new, /* out: first block not matching */ int *stat) /* out: 1 for matches, 0 for not */ { @@ -789,7 +793,7 @@ xfs_rtcheck_range( /* * Read the bitmap block. */ - error = xfs_rtbuf_get(mp, tp, block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, block, 0, rtbufc, &bp); if (error) { return error; } @@ -824,7 +828,6 @@ xfs_rtcheck_range( /* * Different, compute first wrong bit and return. */ - xfs_trans_brelse(tp, bp); i = XFS_RTLOBIT(wdiff) - bit; *new = start + i; *stat = 0; @@ -839,8 +842,7 @@ xfs_rtcheck_range( /* * If done with this block, get the next one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, rtbufc, &bp); if (error) { return error; } @@ -870,7 +872,6 @@ xfs_rtcheck_range( /* * Different, compute first wrong bit and return. */ - xfs_trans_brelse(tp, bp); i += XFS_RTLOBIT(wdiff); *new = start + i; *stat = 0; @@ -885,8 +886,7 @@ xfs_rtcheck_range( /* * If done with this block, get the next one. */ - xfs_trans_brelse(tp, bp); - error = xfs_rtbuf_get(mp, tp, ++block, 0, &bp); + error = xfs_rtbuf_get(mp, tp, ++block, 0, rtbufc, &bp); if (error) { return error; } @@ -915,7 +915,6 @@ xfs_rtcheck_range( /* * Different, compute first wrong bit and return. */ - xfs_trans_brelse(tp, bp); i += XFS_RTLOBIT(wdiff); *new = start + i; *stat = 0; @@ -926,7 +925,6 @@ xfs_rtcheck_range( /* * Successful, return. */ - xfs_trans_brelse(tp, bp); *new = start + i; *stat = 1; return 0; @@ -941,20 +939,21 @@ xfs_rtcheck_alloc_range( xfs_mount_t *mp, /* file system mount point */ xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t bno, /* starting block number of extent */ - xfs_extlen_t len) /* length of extent */ + xfs_extlen_t len, /* length of extent */ + struct xfs_rtbuf_cache *rtbufc) /* in/out: cached blocks */ { xfs_rtblock_t new; /* dummy for xfs_rtcheck_range */ int stat; int error; - error = xfs_rtcheck_range(mp, tp, bno, len, 0, &new, &stat); + error = xfs_rtcheck_range(mp, tp, bno, len, 0, rtbufc, &new, &stat); if (error) return error; ASSERT(stat); return 0; } #else -#define xfs_rtcheck_alloc_range(m,t,b,l) (0) +#define xfs_rtcheck_alloc_range(m,t,b,l,r) (0) #endif /* * Free an extent in the realtime subvolume. Length is expressed in @@ -968,22 +967,21 @@ xfs_rtfree_extent( { int error; /* error value */ xfs_mount_t *mp; /* file system mount structure */ - xfs_fsblock_t sb; /* summary file block number */ - struct xfs_buf *sumbp = NULL; /* summary file block buffer */ + struct xfs_rtbuf_cache rtbufc = {}; /* cache of realtime blocks */ mp = tp->t_mountp; ASSERT(mp->m_rbmip->i_itemp != NULL); ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); - error = xfs_rtcheck_alloc_range(mp, tp, bno, len); + error = xfs_rtcheck_alloc_range(mp, tp, bno, len, &rtbufc); if (error) return error; /* * Free the range of realtime blocks. */ - error = xfs_rtfree_range(mp, tp, bno, len, &sumbp, &sb); + error = xfs_rtfree_range(mp, tp, bno, len, &rtbufc); if (error) { return error; } @@ -1021,6 +1019,7 @@ xfs_rtalloc_query_range( xfs_rtblock_t high_key; int is_free; int error = 0; + struct xfs_rtbuf_cache rtbufc = {}; if (low_rec->ar_startext > high_rec->ar_startext) return -EINVAL; @@ -1034,13 +1033,14 @@ xfs_rtalloc_query_range( rtstart = low_rec->ar_startext; while (rtstart <= high_key) { /* Is the first block free? */ - error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtend, - &is_free); + error = xfs_rtcheck_range(mp, tp, rtstart, 1, 1, &rtbufc, + &rtend, &is_free); if (error) break; /* How long does the extent go for? */ - error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtend); + error = xfs_rtfind_forw(mp, tp, rtstart, high_key, &rtbufc, + &rtend); if (error) break; @@ -1056,6 +1056,8 @@ xfs_rtalloc_query_range( rtstart = rtend + 1; } + xfs_rtbuf_cache_relse(tp, &rtbufc); + return error; } @@ -1085,11 +1087,14 @@ xfs_rtalloc_extent_is_free( xfs_extlen_t len, bool *is_free) { + struct xfs_rtbuf_cache rtbufc = {}; xfs_rtblock_t end; int matches; int error; - error = xfs_rtcheck_range(mp, tp, start, len, 1, &end, &matches); + error = xfs_rtcheck_range(mp, tp, start, len, 1, &rtbufc, &end, + &matches); + xfs_rtbuf_cache_relse(tp, &rtbufc); if (error) return error; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 16534e9873f6..61ef13286654 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -32,11 +32,10 @@ xfs_rtget_summary( xfs_trans_t *tp, /* transaction pointer */ int log, /* log2 of extent size */ xfs_rtblock_t bbno, /* bitmap block number */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ xfs_suminfo_t *sum) /* out: summary info for this block */ { - return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rbpp, rsb, sum); + return xfs_rtmodify_summary_int(mp, tp, log, bbno, 0, rtbufc, sum); } /* @@ -50,8 +49,7 @@ xfs_rtany_summary( int low, /* low log2 extent size */ int high, /* high log2 extent size */ xfs_rtblock_t bbno, /* bitmap block number */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ int *stat) /* out: any good extents here? */ { int error; /* error value */ @@ -69,7 +67,7 @@ xfs_rtany_summary( /* * Get one summary datum. */ - error = xfs_rtget_summary(mp, tp, log, bbno, rbpp, rsb, &sum); + error = xfs_rtget_summary(mp, tp, log, bbno, rtbufc, &sum); if (error) { return error; } @@ -104,29 +102,27 @@ xfs_rtcopy_summary( xfs_trans_t *tp) /* transaction pointer */ { xfs_rtblock_t bbno; /* bitmap block number */ - struct xfs_buf *bp; /* summary buffer */ + struct xfs_rtbuf_cache rtbufc = {}; /* cache of realtime blocks */ int error; /* error return value */ int log; /* summary level number (log length) */ xfs_suminfo_t sum; /* summary data */ - xfs_fsblock_t sumbno; /* summary block number */ - bp = NULL; for (log = omp->m_rsumlevels - 1; log >= 0; log--) { for (bbno = omp->m_sb.sb_rbmblocks - 1; (xfs_srtblock_t)bbno >= 0; bbno--) { - error = xfs_rtget_summary(omp, tp, log, bbno, &bp, - &sumbno, &sum); + error = xfs_rtget_summary(omp, tp, log, bbno, &rtbufc, + &sum); if (error) return error; if (sum == 0) continue; error = xfs_rtmodify_summary(omp, tp, log, bbno, -sum, - &bp, &sumbno); + &rtbufc); if (error) return error; error = xfs_rtmodify_summary(nmp, tp, log, bbno, sum, - &bp, &sumbno); + &rtbufc); if (error) return error; ASSERT(sum > 0); @@ -144,8 +140,7 @@ xfs_rtallocate_range( xfs_trans_t *tp, /* transaction pointer */ xfs_rtblock_t start, /* start block to allocate */ xfs_extlen_t len, /* length to allocate */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb) /* in/out: summary block number */ + struct xfs_rtbuf_cache *rtbufc) /* in/out: cache of realtime blocks */ { xfs_rtblock_t end; /* end of the allocated extent */ int error; /* error value */ @@ -158,14 +153,14 @@ xfs_rtallocate_range( * We need to find the beginning and end of the extent so we can * properly update the summary. */ - error = xfs_rtfind_back(mp, tp, start, 0, &preblock); + error = xfs_rtfind_back(mp, tp, start, 0, rtbufc, &preblock); if (error) { return error; } /* * Find the next allocated block (end of free extent). */ - error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, + error = xfs_rtfind_forw(mp, tp, end, mp->m_sb.sb_rextents - 1, rtbufc, &postblock); if (error) { return error; @@ -176,7 +171,7 @@ xfs_rtallocate_range( */ error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock + 1 - preblock), - XFS_BITTOBLOCK(mp, preblock), -1, rbpp, rsb); + XFS_BITTOBLOCK(mp, preblock), -1, rtbufc); if (error) { return error; } @@ -187,7 +182,7 @@ xfs_rtallocate_range( if (preblock < start) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(start - preblock), - XFS_BITTOBLOCK(mp, preblock), 1, rbpp, rsb); + XFS_BITTOBLOCK(mp, preblock), 1, rtbufc); if (error) { return error; } @@ -199,7 +194,7 @@ xfs_rtallocate_range( if (postblock > end) { error = xfs_rtmodify_summary(mp, tp, XFS_RTBLOCKLOG(postblock - end), - XFS_BITTOBLOCK(mp, end + 1), 1, rbpp, rsb); + XFS_BITTOBLOCK(mp, end + 1), 1, rtbufc); if (error) { return error; } @@ -207,7 +202,7 @@ xfs_rtallocate_range( /* * Modify the bitmap to mark this extent allocated. */ - error = xfs_rtmodify_range(mp, tp, start, len, 0); + error = xfs_rtmodify_range(mp, tp, start, len, 0, rtbufc); return error; } @@ -226,8 +221,7 @@ xfs_rtallocate_extent_block( xfs_extlen_t maxlen, /* maximum length to allocate */ xfs_extlen_t *len, /* out: actual length allocated */ xfs_rtblock_t *nextp, /* out: next block to try */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ xfs_extlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { @@ -254,7 +248,8 @@ xfs_rtallocate_extent_block( * See if there's a free extent of maxlen starting at i. * If it's not so then next will contain the first non-free. */ - error = xfs_rtcheck_range(mp, tp, i, maxlen, 1, &next, &stat); + error = xfs_rtcheck_range(mp, tp, i, maxlen, 1, rtbufc, &next, + &stat); if (error) { return error; } @@ -262,8 +257,7 @@ xfs_rtallocate_extent_block( /* * i for maxlen is all free, allocate and return that. */ - error = xfs_rtallocate_range(mp, tp, i, maxlen, rbpp, - rsb); + error = xfs_rtallocate_range(mp, tp, i, maxlen, rtbufc); if (error) { return error; } @@ -290,7 +284,7 @@ xfs_rtallocate_extent_block( * If not done yet, find the start of the next free space. */ if (next < end) { - error = xfs_rtfind_forw(mp, tp, next, end, &i); + error = xfs_rtfind_forw(mp, tp, next, end, rtbufc, &i); if (error) { return error; } @@ -315,7 +309,7 @@ xfs_rtallocate_extent_block( /* * Allocate besti for bestlen & return that. */ - error = xfs_rtallocate_range(mp, tp, besti, bestlen, rbpp, rsb); + error = xfs_rtallocate_range(mp, tp, besti, bestlen, rtbufc); if (error) { return error; } @@ -344,9 +338,8 @@ xfs_rtallocate_extent_exact( xfs_rtblock_t bno, /* starting block number to allocate */ xfs_extlen_t minlen, /* minimum length to allocate */ xfs_extlen_t maxlen, /* maximum length to allocate */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ xfs_extlen_t *len, /* out: actual length allocated */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ xfs_extlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { @@ -359,7 +352,8 @@ xfs_rtallocate_extent_exact( /* * Check if the range in question (for maxlen) is free. */ - error = xfs_rtcheck_range(mp, tp, bno, maxlen, 1, &next, &isfree); + error = xfs_rtcheck_range(mp, tp, bno, maxlen, 1, rtbufc, &next, + &isfree); if (error) { return error; } @@ -367,7 +361,7 @@ xfs_rtallocate_extent_exact( /* * If it is, allocate it and return success. */ - error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb); + error = xfs_rtallocate_range(mp, tp, bno, maxlen, rtbufc); if (error) { return error; } @@ -402,7 +396,7 @@ xfs_rtallocate_extent_exact( /* * Allocate what we can and return it. */ - error = xfs_rtallocate_range(mp, tp, bno, maxlen, rbpp, rsb); + error = xfs_rtallocate_range(mp, tp, bno, maxlen, rtbufc); if (error) { return error; } @@ -424,8 +418,7 @@ xfs_rtallocate_extent_near( xfs_extlen_t minlen, /* minimum length to allocate */ xfs_extlen_t maxlen, /* maximum length to allocate */ xfs_extlen_t *len, /* out: actual length allocated */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ xfs_extlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { @@ -456,8 +449,8 @@ xfs_rtallocate_extent_near( /* * Try the exact allocation first. */ - error = xfs_rtallocate_extent_exact(mp, tp, bno, minlen, maxlen, len, - rbpp, rsb, prod, &r); + error = xfs_rtallocate_extent_exact(mp, tp, bno, minlen, maxlen, rtbufc, + len, prod, &r); if (error) { return error; } @@ -481,7 +474,7 @@ xfs_rtallocate_extent_near( * starting in this bitmap block. */ error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1, - bbno + i, rbpp, rsb, &any); + bbno + i, rtbufc, &any); if (error) { return error; } @@ -499,8 +492,8 @@ xfs_rtallocate_extent_near( * this block. */ error = xfs_rtallocate_extent_block(mp, tp, - bbno + i, minlen, maxlen, len, &n, rbpp, - rsb, prod, &r); + bbno + i, minlen, maxlen, len, &n, + rtbufc, prod, &r); if (error) { return error; } @@ -529,7 +522,7 @@ xfs_rtallocate_extent_near( */ error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1, - bbno + j, rbpp, rsb, &any); + bbno + j, rtbufc, &any); if (error) { return error; } @@ -545,7 +538,7 @@ xfs_rtallocate_extent_near( continue; error = xfs_rtallocate_extent_block(mp, tp, bbno + j, minlen, maxlen, - len, &n, rbpp, rsb, prod, &r); + len, &n, rtbufc, prod, &r); if (error) { return error; } @@ -566,8 +559,8 @@ xfs_rtallocate_extent_near( * that we found. */ error = xfs_rtallocate_extent_block(mp, tp, - bbno + i, minlen, maxlen, len, &n, rbpp, - rsb, prod, &r); + bbno + i, minlen, maxlen, len, &n, + rtbufc, prod, &r); if (error) { return error; } @@ -626,8 +619,7 @@ xfs_rtallocate_extent_size( xfs_extlen_t minlen, /* minimum length to allocate */ xfs_extlen_t maxlen, /* maximum length to allocate */ xfs_extlen_t *len, /* out: actual length allocated */ - struct xfs_buf **rbpp, /* in/out: summary block buffer */ - xfs_fsblock_t *rsb, /* in/out: summary block number */ + struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ xfs_extlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { @@ -656,7 +648,7 @@ xfs_rtallocate_extent_size( /* * Get the summary for this level/block. */ - error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb, + error = xfs_rtget_summary(mp, tp, l, i, rtbufc, &sum); if (error) { return error; @@ -670,7 +662,7 @@ xfs_rtallocate_extent_size( * Try allocating the extent. */ error = xfs_rtallocate_extent_block(mp, tp, i, maxlen, - maxlen, len, &n, rbpp, rsb, prod, &r); + maxlen, len, &n, rtbufc, prod, &r); if (error) { return error; } @@ -715,7 +707,7 @@ xfs_rtallocate_extent_size( /* * Get the summary information for this level/block. */ - error = xfs_rtget_summary(mp, tp, l, i, rbpp, rsb, + error = xfs_rtget_summary(mp, tp, l, i, rtbufc, &sum); if (error) { return error; @@ -733,7 +725,7 @@ xfs_rtallocate_extent_size( error = xfs_rtallocate_extent_block(mp, tp, i, XFS_RTMAX(minlen, 1 << l), XFS_RTMIN(maxlen, (1 << (l + 1)) - 1), - len, &n, rbpp, rsb, prod, &r); + len, &n, rtbufc, prod, &r); if (error) { return error; } @@ -922,7 +914,6 @@ xfs_growfs_rt( xfs_extlen_t rbmblocks; /* current number of rt bitmap blocks */ xfs_extlen_t rsumblocks; /* current number of rt summary blks */ xfs_sb_t *sbp; /* old superblock */ - xfs_fsblock_t sumbno; /* summary block number */ uint8_t *rsum_cache; /* old summary cache */ sbp = &mp->m_sb; @@ -1025,6 +1016,7 @@ xfs_growfs_rt( bmbno++) { struct xfs_trans *tp; xfs_rfsblock_t nrblocks_step; + struct xfs_rtbuf_cache rtbufc = {}; /* cache of realtime blocks */ *nmp = *mp; nsbp = &nmp->m_sb; @@ -1111,9 +1103,8 @@ xfs_growfs_rt( /* * Free new extent. */ - bp = NULL; error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents, - nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); + nsbp->sb_rextents - sbp->sb_rextents, &rtbufc); if (error) { error_cancel: xfs_trans_cancel(tp); @@ -1185,8 +1176,7 @@ xfs_rtallocate_extent( xfs_mount_t *mp = tp->t_mountp; int error; /* error value */ xfs_rtblock_t r; /* result allocated block */ - xfs_fsblock_t sb; /* summary file block number */ - struct xfs_buf *sumbp; /* summary file block buffer */ + struct xfs_rtbuf_cache rtbufc = {}; /* cache of realtime blocks */ ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL)); ASSERT(minlen > 0 && minlen <= maxlen); @@ -1208,13 +1198,14 @@ xfs_rtallocate_extent( } retry: - sumbp = NULL; + rtbufc.bbuf = NULL; + rtbufc.sbuf = NULL; if (bno == 0) { error = xfs_rtallocate_extent_size(mp, tp, minlen, maxlen, len, - &sumbp, &sb, prod, &r); + &rtbufc, prod, &r); } else { error = xfs_rtallocate_extent_near(mp, tp, bno, minlen, maxlen, - len, &sumbp, &sb, prod, &r); + len, &rtbufc, prod, &r); } if (error) diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 62c7ad79cbb6..888552c4f287 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -101,29 +101,39 @@ xfs_growfs_rt( /* * From xfs_rtbitmap.c */ +struct xfs_rtbuf_cache { + struct xfs_buf *bbuf; /* bitmap block buffer */ + xfs_fsblock_t bblock; /* bitmap block number */ + struct xfs_buf *sbuf; /* summary block buffer */ + xfs_fsblock_t sblock; /* summary block number */ +}; + int xfs_rtbuf_get(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t block, int issum, struct xfs_buf **bpp); + xfs_rtblock_t block, int issum, struct xfs_rtbuf_cache *cache, + struct xfs_buf **bpp); int xfs_rtcheck_range(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, xfs_extlen_t len, int val, - xfs_rtblock_t *new, int *stat); + struct xfs_rtbuf_cache *rtbufc, xfs_rtblock_t *new, + int *stat); int xfs_rtfind_back(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, xfs_rtblock_t limit, - xfs_rtblock_t *rtblock); + struct xfs_rtbuf_cache *rtbufc, xfs_rtblock_t *rtblock); int xfs_rtfind_forw(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, xfs_rtblock_t limit, - xfs_rtblock_t *rtblock); + struct xfs_rtbuf_cache *rtbufc, xfs_rtblock_t *rtblock); int xfs_rtmodify_range(struct xfs_mount *mp, struct xfs_trans *tp, - xfs_rtblock_t start, xfs_extlen_t len, int val); + xfs_rtblock_t start, xfs_extlen_t len, int val, + struct xfs_rtbuf_cache *rtbufc); int xfs_rtmodify_summary_int(struct xfs_mount *mp, struct xfs_trans *tp, int log, xfs_rtblock_t bbno, int delta, - struct xfs_buf **rbpp, xfs_fsblock_t *rsb, + struct xfs_rtbuf_cache *rtbufc, xfs_suminfo_t *sum); int xfs_rtmodify_summary(struct xfs_mount *mp, struct xfs_trans *tp, int log, - xfs_rtblock_t bbno, int delta, struct xfs_buf **rbpp, - xfs_fsblock_t *rsb); + xfs_rtblock_t bbno, int delta, + struct xfs_rtbuf_cache *rtbufc); int xfs_rtfree_range(struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtblock_t start, xfs_extlen_t len, - struct xfs_buf **rbpp, xfs_fsblock_t *rsb); + struct xfs_rtbuf_cache *rtbufc); int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp, const struct xfs_rtalloc_rec *low_rec, const struct xfs_rtalloc_rec *high_rec, From patchwork Tue Jun 20 21:32:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 13286457 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48AE9EB64DB for ; Tue, 20 Jun 2023 21:32:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230146AbjFTVc0 (ORCPT ); Tue, 20 Jun 2023 17:32:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229538AbjFTVcZ (ORCPT ); Tue, 20 Jun 2023 17:32:25 -0400 Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 95BD3170F for ; Tue, 20 Jun 2023 14:32:24 -0700 (PDT) Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-666e5f0d60bso2373008b3a.3 for ; Tue, 20 Jun 2023 14:32:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20221208.gappssmtp.com; s=20221208; t=1687296744; x=1689888744; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QT1zigfHSV1GnJKYRoYuLlUr1mny5O2aWJ3vK3uEwjw=; b=qOCwQHPddSbfdRv6noRuAqtmFp+zz33lu04fWAmTJzKYa08MmMA2BmJfB09xzZHuVG wwvlQUUvQ1KBlp90Dz8bpskHIshFI8vmWT3gNdlbp4vvT2UcxDWDlcHaLAB6+HipEoTt pY7zNloxrNaw87rrwRicJkD7Rx2jfhxGpKhyHO+mOqG8ZL2dxy0RJldFE/UXMAYP8qBj 2FSqFnfQQFPtmlupTlznHz+g3y2+F3dW0ESLsY5Zh6ix2IB0F4TZNxG/+RiKUHJ+8dJC Epma/ZDByEiBOKkmDLg7wQA0lfrgo56t3XNySNbdv2PuigDyrMnpIU7W2hVCX6twBZlR w/hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687296744; x=1689888744; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QT1zigfHSV1GnJKYRoYuLlUr1mny5O2aWJ3vK3uEwjw=; b=kRIUOLeWVflTRbfHpoVnJSkT/lfj8KbbTm5IYNNtfN4vVjqPBMwu0lsDnqtcCcqO94 8EL9EVo/6RQdWJquWO5GSWdAlbGfLuCjVOiiA8hbaLGOfSj+q+OGkLN6mBCfbDLWHR1E tmgA8z03R4J3d/tNslOnxDYFxU6p+FGsFQ+Aq9yYyz34zafFT/LMND2EwVlRuv4aJmpv 5m1M3EHJt7ACQh8eZY7rBBiolmMMA7Yb89UUhCPgxpt0H+K4diecmDBXeGBjB7gTVpDt 4WrHuAvyxTKMVwuAxiGlj4Oe4FVytvymbAzT+jnt3Vk8BfYTgiVvFlKRjkDd8sewhDrQ DJ+A== X-Gm-Message-State: AC+VfDx+x8QmMwScjclvu281Ghu1bAZyHfKiuuyboPbsRIhA/t16mTH2 NO+bM2Mr0ojLO3BJqdvdaKIMOMve67HX1VuHNb4= X-Google-Smtp-Source: ACHHUZ4DkoER6MsMcneSKD+VGBXlQ/9I0yePuR7vWwOHYsaPFNOdFBd6AN3GguDQ382xaxf0Ir+pZA== X-Received: by 2002:a05:6a00:1482:b0:65e:ec60:b019 with SMTP id v2-20020a056a00148200b0065eec60b019mr10972105pfu.25.1687296743706; Tue, 20 Jun 2023 14:32:23 -0700 (PDT) Received: from telecaster.hsd1.wa.comcast.net ([2620:10d:c090:400::5:ea8e]) by smtp.gmail.com with ESMTPSA id 5-20020aa79205000000b0064d3a9def35sm1688188pfo.188.2023.06.20.14.32.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jun 2023 14:32:23 -0700 (PDT) From: Omar Sandoval To: linux-xfs@vger.kernel.org Cc: "Darrick J . Wong" , kernel-team@fb.com, Prashant Nema Subject: [PATCH 2/6] xfs: invert the realtime summary cache Date: Tue, 20 Jun 2023 14:32:12 -0700 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Omar Sandoval In commit 355e3532132b ("xfs: cache minimum realtime summary level"), I added a cache of the minimum level of the realtime summary that has any free extents. However, it turns out that the _maximum_ level is more useful for upcoming optimizations, and basically equivalent for the existing usage. So, let's change the meaning of the cache to be the maximum level + 1, or 0 if there are no free extents. Signed-off-by: Omar Sandoval --- fs/xfs/libxfs/xfs_rtbitmap.c | 6 +++--- fs/xfs/xfs_mount.h | 6 +++--- fs/xfs/xfs_rtalloc.c | 31 +++++++++++++++++++------------ 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rtbitmap.c b/fs/xfs/libxfs/xfs_rtbitmap.c index 1a832c9a412f..d9493f64adfc 100644 --- a/fs/xfs/libxfs/xfs_rtbitmap.c +++ b/fs/xfs/libxfs/xfs_rtbitmap.c @@ -503,10 +503,10 @@ xfs_rtmodify_summary_int( *sp += delta; if (mp->m_rsum_cache) { - if (*sp == 0 && log == mp->m_rsum_cache[bbno]) - mp->m_rsum_cache[bbno]++; - if (*sp != 0 && log < mp->m_rsum_cache[bbno]) + if (*sp == 0 && log + 1 == mp->m_rsum_cache[bbno]) mp->m_rsum_cache[bbno] = log; + if (*sp != 0 && log >= mp->m_rsum_cache[bbno]) + mp->m_rsum_cache[bbno] = log + 1; } xfs_trans_log_buf(tp, bp, first, first + sizeof(*sp) - 1); } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 6c09f89534d3..964541c36730 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -103,9 +103,9 @@ typedef struct xfs_mount { /* * Optional cache of rt summary level per bitmap block with the - * invariant that m_rsum_cache[bbno] <= the minimum i for which - * rsum[i][bbno] != 0. Reads and writes are serialized by the rsumip - * inode lock. + * invariant that m_rsum_cache[bbno] > the maximum i for which + * rsum[i][bbno] != 0, or 0 if rsum[i][bbno] == 0 for all i. + * Reads and writes are serialized by the rsumip inode lock. */ uint8_t *m_rsum_cache; struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 61ef13286654..d3c76532d20e 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -56,14 +56,19 @@ xfs_rtany_summary( int log; /* loop counter, log2 of ext. size */ xfs_suminfo_t sum; /* summary data */ - /* There are no extents at levels < m_rsum_cache[bbno]. */ - if (mp->m_rsum_cache && low < mp->m_rsum_cache[bbno]) - low = mp->m_rsum_cache[bbno]; + /* There are no extents at levels >= m_rsum_cache[bbno]. */ + if (mp->m_rsum_cache) { + high = min(high, mp->m_rsum_cache[bbno] - 1); + if (low > high) { + *stat = 0; + return 0; + } + } /* * Loop over logs of extent sizes. */ - for (log = low; log <= high; log++) { + for (log = high; log >= low; log--) { /* * Get one summary datum. */ @@ -84,9 +89,9 @@ xfs_rtany_summary( */ *stat = 0; out: - /* There were no extents at levels < log. */ - if (mp->m_rsum_cache && log > mp->m_rsum_cache[bbno]) - mp->m_rsum_cache[bbno] = log; + /* There were no extents at levels > log. */ + if (mp->m_rsum_cache && log + 1 < mp->m_rsum_cache[bbno]) + mp->m_rsum_cache[bbno] = log + 1; return 0; } @@ -878,12 +883,14 @@ xfs_alloc_rsum_cache( xfs_extlen_t rbmblocks) /* number of rt bitmap blocks */ { /* - * The rsum cache is initialized to all zeroes, which is trivially a - * lower bound on the minimum level with any free extents. We can - * continue without the cache if it couldn't be allocated. + * The rsum cache is initialized to the maximum value, which is + * trivially an upper bound on the maximum level with any free extents. + * We can continue without the cache if it couldn't be allocated. */ - mp->m_rsum_cache = kvzalloc(rbmblocks, GFP_KERNEL); - if (!mp->m_rsum_cache) + mp->m_rsum_cache = kvmalloc(rbmblocks, GFP_KERNEL); + if (mp->m_rsum_cache) + memset(mp->m_rsum_cache, -1, rbmblocks); + else xfs_warn(mp, "could not allocate realtime summary cache"); } From patchwork Tue Jun 20 21:32:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 13286458 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 749D0EB64D7 for ; Tue, 20 Jun 2023 21:32:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230180AbjFTVc1 (ORCPT ); Tue, 20 Jun 2023 17:32:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229538AbjFTVc0 (ORCPT ); Tue, 20 Jun 2023 17:32:26 -0400 Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EF3F4170F for ; Tue, 20 Jun 2023 14:32:25 -0700 (PDT) Received: by mail-pf1-x42a.google.com with SMTP id d2e1a72fcca58-6686ef86110so1839181b3a.2 for ; Tue, 20 Jun 2023 14:32:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20221208.gappssmtp.com; s=20221208; t=1687296745; x=1689888745; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=K/SOgPg4HXQxCqVyHH/RFKnhs54sjw+CDmLCig4qZxM=; b=bTnItDmeZ63NjsrsKmRSDz7akZTQoeKWuJdeAXAJrqcBBII2oPKFeTnypbJVkUe63u qn3p42RCrNDHckhvs6VDo8pVmMmwoLFOsM/z0x6y5of7G+/VdXwZNj4Z81sACiorNb1t Bb1XGVZeDh5yMyT2hpX9uxrUxmIrEPc47SBxz4SXVtP6jOeyvC+tH7NG47zkrtdTrUD9 XNq05Ca3Hn7H8aE01bzKGzYgYc4+w/8hOFrUOieaVoiRGBGS1DVuiJTsG89LZtqOD51w VVK3VSmG2r9/JHCFRJKd6QTVDzvMDiME1mxC9mPEuoBPQds7STW7RmpZrEw6JGSiS69b aJ/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687296745; x=1689888745; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=K/SOgPg4HXQxCqVyHH/RFKnhs54sjw+CDmLCig4qZxM=; b=WE7RPXHjkXQ7G8RESqa5pxpkhqErdK+49+qv2WgtLqfWeLHV3Jog0sSC/sp1Ha7nEX G2jfXBgFCZI3+gLqNho7X4MdSXB2oHjuJ0tVp6HeXXbWWo4nO4PnphlRZtmKEjmIfukq 2XpKHH1GMB/niBPZfnTQCOiaTiq6UpYH+ccjZ3tOmXdWUtq+pS8Y/WqdK7nCfpu7tyCg BNFEs16XGj9xKDYMhyJBQ071vU4u+lQcuxlJnvndXilkfAoGKWsauR4iloxM7u+SxY5s m8CzsqVGxA3lRFpVIQDiyYs54sUc1ykn76cnq3BVi26kAbGBpP1jogrY5gY7FqGiqbD5 FItg== X-Gm-Message-State: AC+VfDwJOOZEVM0r0M9npmAyGbDOI0SJnBwMB2cVTEQf3gW0F1JM67hY WTiROZhfAnLp1beQtPkU59Ryh6J7/uKGCWKlyMs= X-Google-Smtp-Source: ACHHUZ59GOfqQGAKuUNFtVbDKAUhbQKlxHZGPbgM8Qh/v7Yt5uoYhggQfRB79nbMoCdyhwc5QCMAVw== X-Received: by 2002:a05:6a00:b8f:b0:666:5fc4:36b1 with SMTP id g15-20020a056a000b8f00b006665fc436b1mr10864290pfj.26.1687296744951; Tue, 20 Jun 2023 14:32:24 -0700 (PDT) Received: from telecaster.hsd1.wa.comcast.net ([2620:10d:c090:400::5:ea8e]) by smtp.gmail.com with ESMTPSA id 5-20020aa79205000000b0064d3a9def35sm1688188pfo.188.2023.06.20.14.32.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jun 2023 14:32:24 -0700 (PDT) From: Omar Sandoval To: linux-xfs@vger.kernel.org Cc: "Darrick J . Wong" , kernel-team@fb.com, Prashant Nema Subject: [PATCH 3/6] xfs: return maximum free size from xfs_rtany_summary() Date: Tue, 20 Jun 2023 14:32:13 -0700 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Omar Sandoval Instead of only returning whether there is any free space, return the maximum size, which is fast thanks to the previous commit. This will be used by two upcoming optimizations. Signed-off-by: Omar Sandoval Reviewed-by: Darrick J. Wong --- fs/xfs/xfs_rtalloc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index d3c76532d20e..ba7d42e0090f 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -50,7 +50,7 @@ xfs_rtany_summary( int high, /* high log2 extent size */ xfs_rtblock_t bbno, /* bitmap block number */ struct xfs_rtbuf_cache *rtbufc, /* in/out: cache of realtime blocks */ - int *stat) /* out: any good extents here? */ + int *maxlog) /* out: maximum log2 extent size free */ { int error; /* error value */ int log; /* loop counter, log2 of ext. size */ @@ -60,7 +60,7 @@ xfs_rtany_summary( if (mp->m_rsum_cache) { high = min(high, mp->m_rsum_cache[bbno] - 1); if (low > high) { - *stat = 0; + *maxlog = -1; return 0; } } @@ -80,14 +80,14 @@ xfs_rtany_summary( * If there are any, return success. */ if (sum) { - *stat = 1; + *maxlog = log; goto out; } } /* * Found nothing, return failure. */ - *stat = 0; + *maxlog = -1; out: /* There were no extents at levels > log. */ if (mp->m_rsum_cache && log + 1 < mp->m_rsum_cache[bbno]) @@ -427,7 +427,7 @@ xfs_rtallocate_extent_near( xfs_extlen_t prod, /* extent product factor */ xfs_rtblock_t *rtblock) /* out: start block allocated */ { - int any; /* any useful extents from summary */ + int maxlog; /* maximum useful extent from summary */ xfs_rtblock_t bbno; /* bitmap block number */ int error; /* error value */ int i; /* bitmap block offset (loop control) */ @@ -479,7 +479,7 @@ xfs_rtallocate_extent_near( * starting in this bitmap block. */ error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1, - bbno + i, rtbufc, &any); + bbno + i, rtbufc, &maxlog); if (error) { return error; } @@ -487,7 +487,7 @@ xfs_rtallocate_extent_near( * If there are any useful extents starting here, try * allocating one. */ - if (any) { + if (maxlog >= 0) { /* * On the positive side of the starting location. */ @@ -527,7 +527,7 @@ xfs_rtallocate_extent_near( */ error = xfs_rtany_summary(mp, tp, log2len, mp->m_rsumlevels - 1, - bbno + j, rtbufc, &any); + bbno + j, rtbufc, &maxlog); if (error) { return error; } @@ -539,7 +539,7 @@ xfs_rtallocate_extent_near( * extent given, we've already tried * that allocation, don't do it again. */ - if (any) + if (maxlog >= 0) continue; error = xfs_rtallocate_extent_block(mp, tp, bbno + j, minlen, maxlen, From patchwork Tue Jun 20 21:32:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 13286459 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27A78EB64DC for ; Tue, 20 Jun 2023 21:32:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229749AbjFTVca (ORCPT ); Tue, 20 Jun 2023 17:32:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230184AbjFTVc2 (ORCPT ); Tue, 20 Jun 2023 17:32:28 -0400 Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 68F80170F for ; Tue, 20 Jun 2023 14:32:27 -0700 (PDT) Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-25ecc896007so3139312a91.3 for ; Tue, 20 Jun 2023 14:32:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20221208.gappssmtp.com; s=20221208; t=1687296746; x=1689888746; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=WboN94qfKzpU+jB/4h7hJR+vGuTsRfN/meMwasv9cLQ=; b=LQdUiATfIsdu5vGz/c2yElN90Yu0qMLIFDi4f5kH43o0Pg1kWrspIcVOJ5IbwqYGiq NnmgWp5WrnaTzSmvXVGR7F7pQANV6V9i81VRvHFuEItgzX/l6l0nOgZfKCFtw1fPqQdZ oQV57OLKNdl3UlO27XrHnf921kF2UDhMIFNtMVSTOMbvbZCoFm97s/VMw8hvA2KsnMyn T3duUVI342Xbzj2lMQU4GccKWFeiXVqvhZPU+uCAFN6a62yBtdpC0NoWPRoLqVauxB/Z AxbWSVtNbczj3gmEGTImVPLc9t4VD3qgREo+SxFrI2QOcDH5spfayjyQwfHsWcTHAaPz EMCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687296746; x=1689888746; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=WboN94qfKzpU+jB/4h7hJR+vGuTsRfN/meMwasv9cLQ=; b=V2mWUgBx9JpMRe/alSd3U20sdVt45fo/KuiRe6vuBsQY2Mx7oNBFSRwV7/FWOTX4A4 A6yyEuz3aOfOcBV3yIt5t201y3WvICJEkcXvzcwXsGj+5UP78k79yqKprFEmf+BPEYEi FyFkK/GT6ZSm/rGhsu1K8PMYgMg5khzF4YuMPXDFV4ak8DWKyVXTazZKaPIqx4eGIwjj T/N36so8JHVZpJ4EFcigrzafDX3W+s4MF68mtvIk++akJNZAY+23/Cx/BC1fJOOd61v+ eVoHjMYgpAEA2XAsdZL7YWWEcN9+6JdGJ+MgZpbqsWAVuizZoU501n1ZklWhBJPfcPGi 4tWg== X-Gm-Message-State: AC+VfDzgH4FCmdhtcwD7oA+i5CgmWMUAxZDn0IERcunxeG13L6KNIHhQ vygJLbd2vhDx5GDrEqUdHB3yRbtRGL/HRPM2Ebs= X-Google-Smtp-Source: ACHHUZ46zMBIuHhbA1cHt4gmbhEPXfsXAtG4TKf1sfa8U3qwcyACCF32a6ngLyOif+03u3G88zfu5w== X-Received: by 2002:a05:6a20:3c92:b0:122:60e8:10e1 with SMTP id b18-20020a056a203c9200b0012260e810e1mr4755641pzj.31.1687296746367; Tue, 20 Jun 2023 14:32:26 -0700 (PDT) Received: from telecaster.hsd1.wa.comcast.net ([2620:10d:c090:400::5:ea8e]) by smtp.gmail.com with ESMTPSA id 5-20020aa79205000000b0064d3a9def35sm1688188pfo.188.2023.06.20.14.32.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jun 2023 14:32:25 -0700 (PDT) From: Omar Sandoval To: linux-xfs@vger.kernel.org Cc: "Darrick J . Wong" , kernel-team@fb.com, Prashant Nema Subject: [PATCH 4/6] xfs: limit maxlen based on available space in xfs_rtallocate_extent_near() Date: Tue, 20 Jun 2023 14:32:14 -0700 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Omar Sandoval xfs_rtallocate_extent_near() calls xfs_rtallocate_extent_block() with the minlen and maxlen that were passed to it. xfs_rtallocate_extent_block() then scans the bitmap block looking for a free range of size maxlen. If there is none, it has to scan the whole bitmap block before returning the largest range of at least size minlen. For a fragmented realtime device and a large allocation request, it's almost certain that this will have to search the whole bitmap block, leading to high CPU usage. However, the realtime summary tells us the maximum size available in the bitmap block. We can limit the search in xfs_rtallocate_extent_block() to that size and often stop before scanning the whole bitmap block. Signed-off-by: Omar Sandoval --- fs/xfs/xfs_rtalloc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index ba7d42e0090f..d079dfb77c73 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -488,6 +488,8 @@ xfs_rtallocate_extent_near( * allocating one. */ if (maxlog >= 0) { + xfs_extlen_t maxavail = + min(maxlen, ((xfs_extlen_t)1 << (maxlog + 1)) - 1); /* * On the positive side of the starting location. */ @@ -497,7 +499,7 @@ xfs_rtallocate_extent_near( * this block. */ error = xfs_rtallocate_extent_block(mp, tp, - bbno + i, minlen, maxlen, len, &n, + bbno + i, minlen, maxavail, len, &n, rtbufc, prod, &r); if (error) { return error; @@ -542,7 +544,7 @@ xfs_rtallocate_extent_near( if (maxlog >= 0) continue; error = xfs_rtallocate_extent_block(mp, - tp, bbno + j, minlen, maxlen, + tp, bbno + j, minlen, maxavail, len, &n, rtbufc, prod, &r); if (error) { return error; @@ -564,7 +566,7 @@ xfs_rtallocate_extent_near( * that we found. */ error = xfs_rtallocate_extent_block(mp, tp, - bbno + i, minlen, maxlen, len, &n, + bbno + i, minlen, maxavail, len, &n, rtbufc, prod, &r); if (error) { return error; From patchwork Tue Jun 20 21:32:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 13286462 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05D70EB64D7 for ; Tue, 20 Jun 2023 21:32:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230209AbjFTVca (ORCPT ); Tue, 20 Jun 2023 17:32:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52504 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230199AbjFTVc3 (ORCPT ); Tue, 20 Jun 2023 17:32:29 -0400 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AA1FF170D for ; Tue, 20 Jun 2023 14:32:28 -0700 (PDT) Received: by mail-pf1-x436.google.com with SMTP id d2e1a72fcca58-6687446eaccso2515601b3a.3 for ; Tue, 20 Jun 2023 14:32:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20221208.gappssmtp.com; s=20221208; t=1687296748; x=1689888748; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gxPBD81xyWEubrJfd9aN+qxmAVvYSI724CWx+9oAagA=; b=mu4spGCJSXj4h7en49OUt++WLI2SMw2RPc9JdIcBfpiTdAuxlIvZCuTICRIdvjBZ6E Exr+8hoaNvzpZ2n5WqRi41ZsETC0BDP9kPqIcwmOcKN3WDbCArRkk+LFlh38F7ygHzl/ 2eRkFoDL9D+rwc6A+oK8XLqZkWvPvZR2m+3kt8NVrRsGw4D+cMEV+Qaqso17wBKM3pQ+ HA2UCfUZyHDLdE7idVdbWzN9aThX5ibD+wNwg+EssIQdl7jKWSbBGschf1B9Q9PO/Y2C qXPavujX7vCzJ1Dm3D/AWAmRJOUCTGglpXQHYxtb6GeaZxBMVSHVNq9q1Yqv9LS0/HMM fSxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687296748; x=1689888748; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gxPBD81xyWEubrJfd9aN+qxmAVvYSI724CWx+9oAagA=; b=LY6A7hNPCl+6q6wLHSQWX17k0P96L7m+8gsCmwL2L+i2IMDJ6xZN1EGh6VMuxNBbvh JU9u6kKA54AhHxpGKzdDnIUMsAOYF3NjMW/sYVWrNPjXJ4bIOGJdmiB8ny1s0tOAaVGQ q27u2JT3O6dn29+uaaana7w5ssjCy4nFvgmIydp+CCc7SnedOHPqPkeqRllDuWMMkDtN tJImcfQqbXdU9IR+BJ9o8EHvOHOKaE/WYcO422hTtOPncGJ7MtP4NcdjbSO7v1Ndac+9 Ym1HZbRsrlSslpLNuGrbkbTRdAQk1g9cFDr83MgJnQ2heJRjxd7xIR0AjSYba1iEd4s2 K+aQ== X-Gm-Message-State: AC+VfDz4fSKx9V8MqUraOlnVL6ea5Ch/r3wUoZkaCj0RYSOG05IK1LI7 c/WWhrhVO19ldGjuY9k8LUl/9lbg/wKW2k4fssc= X-Google-Smtp-Source: ACHHUZ5cVbBu2xZQeFAKrFHyiMERuRPn505QS08ntrJH+OThNtbex7fshjK2Oy13or+IJ+XbwMGEkA== X-Received: by 2002:a05:6a00:182a:b0:668:6eed:7c18 with SMTP id y42-20020a056a00182a00b006686eed7c18mr13076237pfa.9.1687296747871; Tue, 20 Jun 2023 14:32:27 -0700 (PDT) Received: from telecaster.hsd1.wa.comcast.net ([2620:10d:c090:400::5:ea8e]) by smtp.gmail.com with ESMTPSA id 5-20020aa79205000000b0064d3a9def35sm1688188pfo.188.2023.06.20.14.32.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jun 2023 14:32:27 -0700 (PDT) From: Omar Sandoval To: linux-xfs@vger.kernel.org Cc: "Darrick J . Wong" , kernel-team@fb.com, Prashant Nema Subject: [PATCH 5/6] xfs: don't try redundant allocations in xfs_rtallocate_extent_near() Date: Tue, 20 Jun 2023 14:32:15 -0700 Message-ID: X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Omar Sandoval xfs_rtallocate_extent_near() tries to find a free extent as close to a target bitmap block given by bbno as possible, which may be before or after bbno. Searching backwards has a complication: the realtime summary accounts for free space _starting_ in a bitmap block, but not straddling or ending in a bitmap block. So, when the negative search finds a free extent in the realtime summary, in order to end up closer to the target, it looks for the end of the free extent. For example, if bbno - 2 has a free extent, then it will check bbno - 1, then bbno - 2. But then if bbno - 3 has a free extent, it will check bbno - 1 again, then bbno - 2 again, and then bbno - 3. This results in a quadratic loop, which is completely pointless since the repeated checks won't find anything new. Fix it by remembering where we last checked up to and continue from there. This also obviates the need for a check of the realtime summary. Signed-off-by: Omar Sandoval --- fs/xfs/xfs_rtalloc.c | 46 +++----------------------------------------- 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index d079dfb77c73..4d9d0be2e616 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -468,6 +468,7 @@ xfs_rtallocate_extent_near( } bbno = XFS_BITTOBLOCK(mp, bno); i = 0; + j = -1; ASSERT(minlen != 0); log2len = xfs_highbit32(minlen); /* @@ -518,31 +519,11 @@ xfs_rtallocate_extent_near( else { /* i < 0 */ /* * Loop backwards through the bitmap blocks from - * the starting point-1 up to where we are now. + * where we last checked up to where we are now. * There should be an extent which ends in this * bitmap block and is long enough. */ - for (j = -1; j > i; j--) { - /* - * Grab the summary information for - * this bitmap block. - */ - error = xfs_rtany_summary(mp, tp, - log2len, mp->m_rsumlevels - 1, - bbno + j, rtbufc, &maxlog); - if (error) { - return error; - } - /* - * If there's no extent given in the - * summary that means the extent we - * found must carry over from an - * earlier block. If there is an - * extent given, we've already tried - * that allocation, don't do it again. - */ - if (maxlog >= 0) - continue; + for (; j >= i; j--) { error = xfs_rtallocate_extent_block(mp, tp, bbno + j, minlen, maxavail, len, &n, rtbufc, prod, &r); @@ -557,27 +538,6 @@ xfs_rtallocate_extent_near( return 0; } } - /* - * There weren't intervening bitmap blocks - * with a long enough extent, or the - * allocation didn't work for some reason - * (i.e. it's a little * too short). - * Try to allocate from the summary block - * that we found. - */ - error = xfs_rtallocate_extent_block(mp, tp, - bbno + i, minlen, maxavail, len, &n, - rtbufc, prod, &r); - if (error) { - return error; - } - /* - * If it works, return the extent. - */ - if (r != NULLRTBLOCK) { - *rtblock = r; - return 0; - } } } /* From patchwork Tue Jun 20 21:32:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 13286461 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3181FEB64DD for ; Tue, 20 Jun 2023 21:32:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230211AbjFTVcb (ORCPT ); Tue, 20 Jun 2023 17:32:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230184AbjFTVca (ORCPT ); Tue, 20 Jun 2023 17:32:30 -0400 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E0DE5170D for ; Tue, 20 Jun 2023 14:32:29 -0700 (PDT) Received: by mail-pf1-x434.google.com with SMTP id d2e1a72fcca58-666ecf9a081so3806147b3a.2 for ; Tue, 20 Jun 2023 14:32:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20221208.gappssmtp.com; s=20221208; t=1687296749; x=1689888749; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=A4OGB8ONrfrL7bW0bPYZHX1/QpOi68gd5YAQEg8Yi+A=; b=GiQTf4EqhkrSyk4P/oDo2GKMf8SskHHUOAgGDkqli0ONSSRtGs4bMium+3/Ql5pMgg 9go4d141pj5br/OX2KUycpj3MtE9u32PW5vmnsbBCSv/OuVxbi3+0bkPz5OzuTmMJWOt Y1Iu2rsJZ0HNDH4R7LIWQO17qDNcSP5bq2Db5Emg1mLC2KnRiMnwCDpTVc4pjv2Gfh96 IXc6rMLEnnt8mYzDzCt/Z6GG5chWOqXF9D+HNRslvbM0u3Uhy0WQr6qb8jYVqn56lLmG Ooh8F5ctZRBw9I/pKdIg7PEnzr/x8SfwMYy98KD+Mi7xR/5+K7FNckeXodhS2ue6f600 3xRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687296749; x=1689888749; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=A4OGB8ONrfrL7bW0bPYZHX1/QpOi68gd5YAQEg8Yi+A=; b=R4vUmQtozWZ5wq9P6uhKbRm/DhuczIzbw8grFhIwwQzTf/4KkWxb2qmdr13eckx+K6 OmgJ1N6XtNV2amLCryCPThY/9MINsCuBSwK95/4hrD1qzHt3E8bWxtrN0mBgYBUtlf4J JStyQr1mxy2L9ueAEa28hsZf3bJmZWLBGWK04VONqJZn/75i4W2xGMPZc6NcOAfIbWFD 9hwppb7vAO9eQxFVNBxUh08jrrv2nE1yLD2rPaqj0BcS1KAp46nZ4dgiyLsSu3DqPHmZ eHZD8vErl5Y89tPsqw775zUyrvvmBCx0bhxXXcX5uhyzPamLPYYiyIlKD8r4nfvAXczE w5wg== X-Gm-Message-State: AC+VfDy88SxwXkthkDzhnIx1g7g48FcZT+OULOB7JSfhfQ8saCBq/WwD ywa2oYT+qTTnbVGuPR6iLP2EkV6+tjcv79OQ6yk= X-Google-Smtp-Source: ACHHUZ6LpO34z6guE3CZq38XbRFR2ZdKUKjYJtwy+Z871PC2n9JeDTQfao5SHq4eAkCEZSgkYaWhOA== X-Received: by 2002:a05:6a20:1586:b0:122:79a0:ff74 with SMTP id h6-20020a056a20158600b0012279a0ff74mr3911424pzj.50.1687296749071; Tue, 20 Jun 2023 14:32:29 -0700 (PDT) Received: from telecaster.hsd1.wa.comcast.net ([2620:10d:c090:400::5:ea8e]) by smtp.gmail.com with ESMTPSA id 5-20020aa79205000000b0064d3a9def35sm1688188pfo.188.2023.06.20.14.32.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jun 2023 14:32:28 -0700 (PDT) From: Omar Sandoval To: linux-xfs@vger.kernel.org Cc: "Darrick J . Wong" , kernel-team@fb.com, Prashant Nema Subject: [PATCH 6/6] xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near() Date: Tue, 20 Jun 2023 14:32:16 -0700 Message-ID: <554f3ce85edca54d14cc1e1b22c4207a3e8f36a7.1687296675.git.osandov@osandov.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Omar Sandoval As explained in the previous commit, xfs_rtallocate_extent_near() looks for the end of a free extent when searching backwards from the target bitmap block. Since the previous commit, it searches from the last bitmap block it checked to the bitmap block containing the start of the extent. This may still be more than necessary, since the free extent may not be that long. We know the maximum size of the free extent from the realtime summary. Use that to compute how many bitmap blocks we actually need to check. Signed-off-by: Omar Sandoval Reviewed-by: Darrick J. Wong --- fs/xfs/xfs_rtalloc.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 4d9d0be2e616..2e2eb7c4a648 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -517,12 +517,29 @@ xfs_rtallocate_extent_near( * On the negative side of the starting location. */ else { /* i < 0 */ + int maxblocks; + /* - * Loop backwards through the bitmap blocks from - * where we last checked up to where we are now. - * There should be an extent which ends in this - * bitmap block and is long enough. + * Loop backwards to find the end of the extent + * we found in the realtime summary. + * + * maxblocks is the maximum possible number of + * bitmap blocks from the start of the extent to + * the end of the extent. */ + if (maxlog == 0) + maxblocks = 0; + else if (maxlog < mp->m_blkbit_log) + maxblocks = 1; + else + maxblocks = 2 << (maxlog - mp->m_blkbit_log); + /* + * We need to check bbno + i + maxblocks down to + * bbno + i. We already checked bbno down to + * bbno + j + 1, so we don't need to check those + * again. + */ + j = min(i + maxblocks, j); for (; j >= i; j--) { error = xfs_rtallocate_extent_block(mp, tp, bbno + j, minlen, maxavail,