From patchwork Wed May 9 07:47:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 10388295 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 49DC360170 for ; Wed, 9 May 2018 07:48:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C9D628E08 for ; Wed, 9 May 2018 07:48:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3180D28E65; Wed, 9 May 2018 07:48:44 +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=-2.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9CAA828E08 for ; Wed, 9 May 2018 07:48:43 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6F3CD6B0335; Wed, 9 May 2018 03:48:42 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 67A5E6B0337; Wed, 9 May 2018 03:48:42 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 51B566B0339; Wed, 9 May 2018 03:48:42 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf0-f198.google.com (mail-pf0-f198.google.com [209.85.192.198]) by kanga.kvack.org (Postfix) with ESMTP id 0EB916B0335 for ; Wed, 9 May 2018 03:48:42 -0400 (EDT) Received: by mail-pf0-f198.google.com with SMTP id l85so24007086pfb.18 for ; Wed, 09 May 2018 00:48:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:dkim-signature:from:to:cc:subject:date :message-id:in-reply-to:references; bh=vsIeBz/JXk2hQDm0gEa61hc8AptzrB0JeXzHyVpu3xU=; b=JRPaj4SP9+9cXEkypJPRmLnsgBNYYLgCr1z6tQR1SwaaJRMi4ti+lHpAsSF8Ee9R1+ B2gWsSsUcehFNuI6ED5fXhJh8F0MEvhkb07rUy9ktAmf2T7zUQXUO/igSS7Rf62xbxlP ybFaKLLwfPxWYfYPROQFHs0vAAFDS4Gxk1uYjBROaXfze+me1IimptWBiVUImHOYjRSB QrNcqlvcWYPucsMbO3CrA/kNQQ1jpbFPx+gvDuBM/grzPN0MoV6Qtu9K5HV5IAmk4s5G uO6Kz5dxyNqXNGoyCUMMQG/7c+o9h3ptCNUfzcj2JuB8dL2WX06JiGO0Q/OGAPaKl820 LA/Q== X-Gm-Message-State: ALQs6tBP0WN77c4Y+uMpQtPVcso8LUCKZKUGssLMkoZ0q5SPk6odqFJf M/jDbeEd71xNm3Gr+CZ0Eb/+3ZkW//f59RNCa+j19zCi+QndY/2N1byU8ycp2vvcES4dgJVvMTU JsEK9Bg8KRuox2+5pwhuBr6OBAhogSA5rNbnRoCMzq642xDyxPNYx+aCjb5JNlZM= X-Received: by 10.98.162.30 with SMTP id m30mr27210662pff.251.1525852121662; Wed, 09 May 2018 00:48:41 -0700 (PDT) X-Google-Smtp-Source: AB8JxZprjP4l68UyJWDtMk4rDl8snw1qTKa0zBFC7jl8hHtaM+Fjg+dqYiu5E67LtLA6wfAlzzpD X-Received: by 10.98.162.30 with SMTP id m30mr27210623pff.251.1525852120727; Wed, 09 May 2018 00:48:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525852120; cv=none; d=google.com; s=arc-20160816; b=Oa6qnwMq3pR9OgBkElKz5oLxIOCU8K/U0aY4ZAhownaMxSpsnH6/roCiJouuvCkX46 VqOkJLgPlwJL6yOZVUe+qWCjQfjflerneaxP1qh0O/ru5Qja2lFqH+lWgb1xBoNnfzXK VUGgniaPPrA80jYXHKaDtvSoY51SVt3/W6oDu7bnSgdU+nouPH3f3angMlj1Dkh1aPLn LvchZs/NoPGk9Dnj4GaxJFA72bG+HrXO9JQOtPOKkloDpvGiav7M79b+UkFqAgTMjcnZ UA2M9/UaFIwU8EQcdtQs5idivSCo7xHtbxkFNqyesI4gnJTYEv9gI2al0HP+RgwOwRmD Cthg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=vsIeBz/JXk2hQDm0gEa61hc8AptzrB0JeXzHyVpu3xU=; b=B6kSPwYRStDCsLFqLqcEHiR4ggTXvD/X3pqOyBOsMbTZZMNhZFkxzCm9PMaLHLyb1n hdKdP7x4ZCZ+spOM4ZOkMuOUDLOARBTYrBzeHeWUCW9uG//Wr0Oak3crfuCoezqf2k3P 7ktwy3CX0Uap0x1co0qAIHnRRX751X65AkW9Ab6oyu1Vm5j2L51HrfNVY+OTbTc5GqL7 Co7xEIdRlITdSeYPiMjgp6NHRJpujm25RudffUxKZJKPsuG2kkWhqqpGkHDxbjD3HvQa RJ2AdcuHTe5ofpKgzaWzIk27voCSHX0lyA98hh/P9i39kO371VK7b/4yFBZOZCo1nZ+N IBsg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@infradead.org header.s=bombadil.20170209 header.b=EAX7c9Y5; spf=pass (google.com: best guess record for domain of batv+e0efdd19ce80d487e3da+5372+infradead.org+hch@bombadil.srs.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom=BATV+e0efdd19ce80d487e3da+5372+infradead.org+hch@bombadil.srs.infradead.org Received: from bombadil.infradead.org (bombadil.infradead.org. [2607:7c80:54:e::133]) by mx.google.com with ESMTPS id y70si3184723pfg.121.2018.05.09.00.48.40 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 09 May 2018 00:48:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of batv+e0efdd19ce80d487e3da+5372+infradead.org+hch@bombadil.srs.infradead.org designates 2607:7c80:54:e::133 as permitted sender) client-ip=2607:7c80:54:e::133; Authentication-Results: mx.google.com; dkim=pass header.i=@infradead.org header.s=bombadil.20170209 header.b=EAX7c9Y5; spf=pass (google.com: best guess record for domain of batv+e0efdd19ce80d487e3da+5372+infradead.org+hch@bombadil.srs.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom=BATV+e0efdd19ce80d487e3da+5372+infradead.org+hch@bombadil.srs.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=vsIeBz/JXk2hQDm0gEa61hc8AptzrB0JeXzHyVpu3xU=; b=EAX7c9Y5J7AFkwv967iOrmZ8E 46YLNoimKQBnyXZs9r0tY1FvsFuWLFYsQTCVZhuHvM/g4c+qgGGnA2FC04E9OohrU/9VYkHEQSGTA o906NGhrynzBrHqAl4QYDOCou/jF42OMhg/8zIQsQ9IfB+ZB+SQIcUUiVH4po+/d28zL32Gr+gFte 4VoiBWUYMsOljcuKePZeWaAFRuX54I3nN72vQtz0ElolUv813cw4osPhi25JqOhm2uedo+XcQI0lu QQ7aXiae3h2KRsmsbRBdIohDLSPso/8JrTGSNiwcM5EHDI3qZLFoE1w3fXLF5hf7d/0wVv0/eO/Ih cRVq+fDjg==; Received: from 213-225-15-246.nat.highway.a1.net ([213.225.15.246] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1fGJq3-0000oF-CT; Wed, 09 May 2018 07:48:40 +0000 From: Christoph Hellwig To: linux-xfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH 01/33] block: add a lower-level bio_add_page interface Date: Wed, 9 May 2018 09:47:58 +0200 Message-Id: <20180509074830.16196-2-hch@lst.de> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180509074830.16196-1-hch@lst.de> References: <20180509074830.16196-1-hch@lst.de> X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP For the upcoming removal of buffer heads in XFS we need to keep track of the number of outstanding writeback requests per page. For this we need to know if bio_add_page merged a region with the previous bvec or not. Instead of adding additional arguments this refactors bio_add_page to be implemented using three lower level helpers which users like XFS can use directly if they care about the merge decisions. Signed-off-by: Christoph Hellwig --- block/bio.c | 87 ++++++++++++++++++++++++++++++--------------- include/linux/bio.h | 9 +++++ 2 files changed, 67 insertions(+), 29 deletions(-) diff --git a/block/bio.c b/block/bio.c index 53e0f0a1ed94..6ceba6adbf42 100644 --- a/block/bio.c +++ b/block/bio.c @@ -773,7 +773,7 @@ int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page return 0; } - if (bio->bi_vcnt >= bio->bi_max_vecs) + if (bio_full(bio)) return 0; /* @@ -820,6 +820,59 @@ int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page } EXPORT_SYMBOL(bio_add_pc_page); +/** + * __bio_try_merge_page - try adding data to an existing bvec + * @bio: destination bio + * @page: page to add + * @len: length of the range to add + * @off: offset into @page + * + * Try adding the data described at @page + @offset to the last bvec of @bio. + * Return %true on success or %false on failure. This can happen frequently + * for file systems with a block size smaller than the page size. + */ +bool __bio_try_merge_page(struct bio *bio, struct page *page, + unsigned int len, unsigned int off) +{ + if (bio->bi_vcnt > 0) { + struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1]; + + if (page == bv->bv_page && off == bv->bv_offset + bv->bv_len) { + bv->bv_len += len; + bio->bi_iter.bi_size += len; + return true; + } + } + return false; +} +EXPORT_SYMBOL_GPL(__bio_try_merge_page); + +/** + * __bio_add_page - add page to a bio in a new segment + * @bio: destination bio + * @page: page to add + * @len: length of the range to add + * @off: offset into @page + * + * Add the data at @page + @offset to @bio as a new bvec. The caller must + * ensure that @bio has space for another bvec. + */ +void __bio_add_page(struct bio *bio, struct page *page, + unsigned int len, unsigned int off) +{ + struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt]; + + WARN_ON_ONCE(bio_full(bio)); + + bv->bv_page = page; + bv->bv_offset = off; + bv->bv_len = len; + + bio->bi_iter.bi_size += len; + bio->bi_vcnt++; +} +EXPORT_SYMBOL_GPL(__bio_add_page); + /** * bio_add_page - attempt to add page to bio * @bio: destination bio @@ -833,40 +886,16 @@ EXPORT_SYMBOL(bio_add_pc_page); int bio_add_page(struct bio *bio, struct page *page, unsigned int len, unsigned int offset) { - struct bio_vec *bv; - /* * cloned bio must not modify vec list */ if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED))) return 0; - - /* - * For filesystems with a blocksize smaller than the pagesize - * we will often be called with the same page as last time and - * a consecutive offset. Optimize this special case. - */ - if (bio->bi_vcnt > 0) { - bv = &bio->bi_io_vec[bio->bi_vcnt - 1]; - - if (page == bv->bv_page && - offset == bv->bv_offset + bv->bv_len) { - bv->bv_len += len; - goto done; - } + if (!__bio_try_merge_page(bio, page, len, offset)) { + if (bio_full(bio)) + return 0; + __bio_add_page(bio, page, len, offset); } - - if (bio->bi_vcnt >= bio->bi_max_vecs) - return 0; - - bv = &bio->bi_io_vec[bio->bi_vcnt]; - bv->bv_page = page; - bv->bv_len = len; - bv->bv_offset = offset; - - bio->bi_vcnt++; -done: - bio->bi_iter.bi_size += len; return len; } EXPORT_SYMBOL(bio_add_page); diff --git a/include/linux/bio.h b/include/linux/bio.h index ce547a25e8ae..3e73c8bc25ea 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -123,6 +123,11 @@ static inline void *bio_data(struct bio *bio) return NULL; } +static inline bool bio_full(struct bio *bio) +{ + return bio->bi_vcnt >= bio->bi_max_vecs; +} + /* * will die */ @@ -470,6 +475,10 @@ void bio_chain(struct bio *, struct bio *); extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int); extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *, unsigned int, unsigned int); +bool __bio_try_merge_page(struct bio *bio, struct page *page, + unsigned int len, unsigned int off); +void __bio_add_page(struct bio *bio, struct page *page, + unsigned int len, unsigned int off); int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter); struct rq_map_data; extern struct bio *bio_map_user_iov(struct request_queue *,