From patchwork Thu Mar 26 18:27:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heitor Alves de Siqueira X-Patchwork-Id: 1262176 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48pD4w1PVVz9sRY; Fri, 27 Mar 2020 05:28:14 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1jHXEg-0000DB-4m; Thu, 26 Mar 2020 18:28:10 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jHXEe-0000Ct-54 for kernel-team@lists.ubuntu.com; Thu, 26 Mar 2020 18:28:08 +0000 Received: from mail-qk1-f199.google.com ([209.85.222.199]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jHXEd-0007Qd-Oj for kernel-team@lists.ubuntu.com; Thu, 26 Mar 2020 18:28:07 +0000 Received: by mail-qk1-f199.google.com with SMTP id c1so5643501qkg.21 for ; Thu, 26 Mar 2020 11:28:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lqISGhKxyiefAe97SfFjOtXoENRWdFmx/vzzJt60/8E=; b=ofPJik7UZwojXQekllDMKa+gchMtkaMDvVll8T7QC5hJN3oE6DPgekblH6KZ3hG0ZN 55UN83/++rCUtSWs9x1Ti2+lMpYnvXTKJRvKubiQmHHNx2drnHfxY2ngOzERgs8TmgFD LhqTyZ2FmplCxj/NtlbrjrVizRkfyTwYQZGkSgwVxCaLAnow25lt24bP5nhT2cT1lS18 ZiOnvXCTvXdikKphxpyjp49hr+BAeG4u1lrmpjPoJZXaRtzfxIrALVjRrh00rQIDQmXe WcMrjVflzrFrncJaO8Fkl+s/qlnipiKBtWS3HEhmqJHt5y7pShpt0FthFJKBcL0xsocc LzSQ== X-Gm-Message-State: ANhLgQ3l88GOqyCjJr8vtWCjyNwZRuLMzVWRii8B+DoPznOzzVQsHNpV NrIhzOHpUwBlRARRglE/fSZzcVYtlVbut7NIqTIGqGSRbpWCuYx0KhZR5YTGWNAiM21zRHgIXom OoDIsIcawKqwTsq1dzCcIetQ4sDUVwpNRxI2IZEIEkQ== X-Received: by 2002:a0c:f701:: with SMTP id w1mr9753084qvn.126.1585247286334; Thu, 26 Mar 2020 11:28:06 -0700 (PDT) X-Google-Smtp-Source: ADFU+vsavE0QMTYxY/wK1JVPq9HZ8D+KbZ2mbXnsHkteYhwIz+2EneOim4LV8NUZcmXnbdpPYl/cbQ== X-Received: by 2002:a0c:f701:: with SMTP id w1mr9752962qvn.126.1585247285110; Thu, 26 Mar 2020 11:28:05 -0700 (PDT) Received: from localhost.localdomain ([2804:14c:4e3:811a:b62e:99ff:fe3d:c824]) by smtp.gmail.com with ESMTPSA id h11sm1986592qtr.38.2020.03.26.11.28.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Mar 2020 11:28:04 -0700 (PDT) From: Heitor Alves de Siqueira To: kernel-team@lists.ubuntu.com Subject: [SRU][Xenial][PATCH 1/1] block: fix bio_will_gap() for first bvec with offset Date: Thu, 26 Mar 2020 15:27:36 -0300 Message-Id: <20200326182736.1941465-2-halves@canonical.com> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200326182736.1941465-1-halves@canonical.com> References: <20200326182736.1941465-1-halves@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Guilherme Piccoli Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ming Lei BugLink: https://bugs.launchpad.net/bugs/1869229 Commit 729204ef49ec("block: relax check on sg gap") allows us to merge bios, if both are physically contiguous. This change can merge a huge number of small bios, through mkfs for example, mkfs.ntfs running time can be decreased to ~1/10. But if one rq starts with a non-aligned buffer (the 1st bvec's bv_offset is non-zero) and if we allow the merge, it is quite difficult to respect sg gap limit, especially the max segment size, or we risk having an unaligned virtual boundary. This patch tries to avoid the issue by disallowing a merge, if the req starts with an unaligned buffer. Also add comments to explain why the merged segment can't end in unaligned virt boundary. Fixes: 729204ef49ec ("block: relax check on sg gap") Tested-by: Johannes Thumshirn Reviewed-by: Johannes Thumshirn Signed-off-by: Ming Lei Rewrote parts of the commit message and comments. Signed-off-by: Jens Axboe (cherry picked from commit 5a8d75a1b8c99bdc926ba69b7b7dbe4fae81a5af) Signed-off-by: Matthew Ruffell Signed-off-by: Heitor Alves de Siqueira Acked-by: Sultan Alsawaf --- include/linux/blkdev.h | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 7548f332121a..01a696b0a4d3 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1672,12 +1672,36 @@ static inline bool bios_segs_mergeable(struct request_queue *q, return true; } -static inline bool bio_will_gap(struct request_queue *q, struct bio *prev, - struct bio *next) +static inline bool bio_will_gap(struct request_queue *q, + struct request *prev_rq, + struct bio *prev, + struct bio *next) { if (bio_has_data(prev) && queue_virt_boundary(q)) { struct bio_vec pb, nb; + /* + * don't merge if the 1st bio starts with non-zero + * offset, otherwise it is quite difficult to respect + * sg gap limit. We work hard to merge a huge number of small + * single bios in case of mkfs. + */ + if (prev_rq) + bio_get_first_bvec(prev_rq->bio, &pb); + else + bio_get_first_bvec(prev, &pb); + if (pb.bv_offset) + return true; + + /* + * We don't need to worry about the situation that the + * merged segment ends in unaligned virt boundary: + * + * - if 'pb' ends aligned, the merged segment ends aligned + * - if 'pb' ends unaligned, the next bio must include + * one single bvec of 'nb', otherwise the 'nb' can't + * merge with 'pb' + */ bio_get_last_bvec(prev, &pb); bio_get_first_bvec(next, &nb); @@ -1690,12 +1714,12 @@ static inline bool bio_will_gap(struct request_queue *q, struct bio *prev, static inline bool req_gap_back_merge(struct request *req, struct bio *bio) { - return bio_will_gap(req->q, req->biotail, bio); + return bio_will_gap(req->q, req, req->biotail, bio); } static inline bool req_gap_front_merge(struct request *req, struct bio *bio) { - return bio_will_gap(req->q, bio, req->bio); + return bio_will_gap(req->q, NULL, bio, req->bio); } int kblockd_schedule_work(struct work_struct *work);