From patchwork Mon Jan 4 18:24:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Busch X-Patchwork-Id: 7950051 Return-Path: X-Original-To: patchwork-linux-block@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D07E49F1C0 for ; Mon, 4 Jan 2016 18:25:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EC4DA2021B for ; Mon, 4 Jan 2016 18:25:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EDA10201E4 for ; Mon, 4 Jan 2016 18:25:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753051AbcADSZB (ORCPT ); Mon, 4 Jan 2016 13:25:01 -0500 Received: from mga04.intel.com ([192.55.52.120]:9603 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753038AbcADSY6 (ORCPT ); Mon, 4 Jan 2016 13:24:58 -0500 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga104.fm.intel.com with ESMTP; 04 Jan 2016 10:24:57 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,521,1444719600"; d="scan'208";a="853338699" Received: from dcgshare.lm.intel.com ([10.232.118.254]) by orsmga001.jf.intel.com with ESMTP; 04 Jan 2016 10:24:57 -0800 Received: by dcgshare.lm.intel.com (Postfix, from userid 1017) id E237BE0C64; Mon, 4 Jan 2016 11:24:56 -0700 (MST) From: Keith Busch To: linux-nvme@lists.infradead.org, linux-block@vger.kernel.org Cc: Jens Axboe , Greg White , Keith Busch Subject: [PATCH for-4.4] block: split bios to max possible length Date: Mon, 4 Jan 2016 11:24:55 -0700 Message-Id: <1451931895-17474-1-git-send-email-keith.busch@intel.com> X-Mailer: git-send-email 1.7.1 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This allows bio splits in the middle of a vector to form the largest possible bio at the h/w's desired alignment, and guarantees the bio being split will have some data. Previously, if the first vector's length was greater than the allowable amount, the bio would split at a zero length and hit a kernel BUG. The length check is moved after the SG_GAPS check so that check doesn't need to be duplicated in the split case. Fixes: d3805611130af9b911e908af9f67a3f64f4f0914 bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=110231 Signed-off-by: Keith Busch --- block/blk-merge.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/block/blk-merge.c b/block/blk-merge.c index e73846a..e886a7d 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -81,9 +81,6 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, struct bio *new = NULL; bio_for_each_segment(bv, bio, iter) { - if (sectors + (bv.bv_len >> 9) > blk_max_size_offset(q, bio->bi_iter.bi_sector)) - goto split; - /* * If the queue doesn't support SG gaps and adding this * offset would create a gap, disallow it. @@ -91,6 +88,17 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, if (bvprvp && bvec_gap_to_prev(q, bvprvp, bv.bv_offset)) goto split; + if (sectors + (bv.bv_len >> 9) > blk_max_size_offset(q, bio->bi_iter.bi_sector)) { + /* + * Consider this a new segment if we're taking any part + * of this vector. + */ + if (sectors < blk_max_size_offset(q, bio->bi_iter.bi_sector)) + ++nsegs; + sectors = blk_max_size_offset(q, bio->bi_iter.bi_sector); + goto split; + } + if (bvprvp && blk_queue_cluster(q)) { if (seg_size + bv.bv_len > queue_max_segment_size(q)) goto new_segment;