From patchwork Sat Dec 17 10:49:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 9478929 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 668DB60827 for ; Sat, 17 Dec 2016 10:49:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 55E3528583 for ; Sat, 17 Dec 2016 10:49:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 46B4A28588; Sat, 17 Dec 2016 10:49:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 868F928583 for ; Sat, 17 Dec 2016 10:49:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753560AbcLQKti (ORCPT ); Sat, 17 Dec 2016 05:49:38 -0500 Received: from mail-pf0-f196.google.com ([209.85.192.196]:34779 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752729AbcLQKth (ORCPT ); Sat, 17 Dec 2016 05:49:37 -0500 Received: by mail-pf0-f196.google.com with SMTP id y68so5587099pfb.1; Sat, 17 Dec 2016 02:49:37 -0800 (PST) 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; bh=3BplTp8iOpLvIu9Wbt2h4eaocObc5gYCNcLMEJ0Uma0=; b=nq04qyJg4Ze+x+0i8Uwu12lUpBpz6h4LecsM2GfyrR6dBMq9KFyBOA+5e9rtobQ/vY cbM7TtvU5vEYwabEkJ7UhOMErZAkQKUZ+SlyocgyJQL6Wt1OGP4ZQm+byjFmvMIqkgpc l4ZUEFK1otM1xpbSwSSLYmKO17NQjz+vXZBBg9PWk9KmYJAe59xUPVOnbUWJCsJVT21Y ajJ+iwQDuGbWbHxmyCWQYrTUVqv4kf20SlD7M6wjZCzHm9kQI7NdlwSJA00dBya/QIUb tCk+qR/EiTozjhv5Vv3uYRe9EzIUJH3SjA6D3NVjFf+K3gO/mYu9xA8OPaeoAx2oJUoU q71Q== X-Gm-Message-State: AKaTC02heZgnQsbsrvXBQi3n7vPwMtpFypNSrXxgsb2DSHeDa+RjtC2mI4ePMdhsftGo7Q== X-Received: by 10.84.215.148 with SMTP id l20mr16466583pli.120.1481971776857; Sat, 17 Dec 2016 02:49:36 -0800 (PST) Received: from localhost ([45.35.47.137]) by smtp.gmail.com with ESMTPSA id s197sm18145974pgc.38.2016.12.17.02.49.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 17 Dec 2016 02:49:35 -0800 (PST) From: Ming Lei To: Jens Axboe , linux-kernel@vger.kernel.org Cc: linux-block@vger.kernel.org, Christoph Hellwig , Dexuan Cui , Vitaly Kuznetsov , Ming Lei , Keith Busch , Hannes Reinecke , Mike Christie , "Martin K. Petersen" , Toshi Kani , Dan Williams , Damien Le Moal Subject: [PATCH] block: loose check on sg gap Date: Sat, 17 Dec 2016 18:49:09 +0800 Message-Id: <1481971751-4016-1-git-send-email-ming.lei@canonical.com> X-Mailer: git-send-email 2.7.4 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If the last bvec of the 1st bio and the 1st bvec of the next bio are contineous physically, and the latter can be merged to last segment of the 1st bio, we should think they don't violate sg gap(or virt boundary) limit. Both Vitaly and Dexuan reported lots of unmergeable small bios are observed when running mkfs on Hyper-V virtual storage, and performance becomes quite low, so this patch is figured out for fixing the performance issue. The same issue should exist on NVMe too sine it sets virt boundary too. Reported-by: Vitaly Kuznetsov Reported-by: Dexuan Cui Tested-by: Dexuan Cui Cc: Keith Busch Signed-off-by: Ming Lei --- include/linux/blkdev.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 286b2a264383..1ce26e771bcc 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1608,6 +1608,25 @@ static inline bool bvec_gap_to_prev(struct request_queue *q, return __bvec_gap_to_prev(q, bprv, offset); } +/* + * Check if the two bvecs from two bios can be merged to one segment. + * If yes, no need to check gap between the two bios since the 1st bio + * and the 1st bvec in the 2nd bio can be handled in one segment. + */ +static inline bool bios_segs_mergeable(struct request_queue *q, + struct bio *prev, struct bio_vec *prev_last_bv, + struct bio_vec *next_first_bv) +{ + if (!BIOVEC_PHYS_MERGEABLE(prev_last_bv, next_first_bv)) + return false; + if (!BIOVEC_SEG_BOUNDARY(q, prev_last_bv, next_first_bv)) + return false; + if (prev->bi_seg_back_size + next_first_bv->bv_len > + queue_max_segment_size(q)) + return false; + return true; +} + static inline bool bio_will_gap(struct request_queue *q, struct bio *prev, struct bio *next) { @@ -1617,7 +1636,8 @@ static inline bool bio_will_gap(struct request_queue *q, struct bio *prev, bio_get_last_bvec(prev, &pb); bio_get_first_bvec(next, &nb); - return __bvec_gap_to_prev(q, &pb, nb.bv_offset); + if (!bios_segs_mergeable(q, prev, &pb, &nb)) + return __bvec_gap_to_prev(q, &pb, nb.bv_offset); } return false;