From patchwork Fri May 18 16:47:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 10411191 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 7C4416031B for ; Fri, 18 May 2018 16:48:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B351E28643 for ; Fri, 18 May 2018 16:48:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A7594287F3; Fri, 18 May 2018 16:48:41 +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 89F2E28643 for ; Fri, 18 May 2018 16:48:40 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6BC526B05F9; Fri, 18 May 2018 12:48:39 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 647DC6B05FB; Fri, 18 May 2018 12:48:39 -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 4E83F6B05FC; Fri, 18 May 2018 12:48:39 -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 07C266B05F9 for ; Fri, 18 May 2018 12:48:39 -0400 (EDT) Received: by mail-pf0-f198.google.com with SMTP id s16-v6so5065166pfm.1 for ; Fri, 18 May 2018 09:48:38 -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=m9e7LyI0Hb29RdOx1TgmifyTpn9WHrmJ6NNaZ6XE5/E=; b=cJGpXEyVFGT7XyilrHOgXx4BdozzIk4xuTQJNM+SpIFzK1uz3hgtPIS8qNTiVOiVxh RLj5zl+xhDTYlIQVzkFIkpZWKeUXEni0d9/HGqrmGi2H2UqN7f3TBOrv0Zs88Y90PvFE zOwVWBQZKU59C5DD47Z/i32ffg5LPBwfgClqu58JoOn6O1dB7AKGmqf61K3OKN0TMTgp n4T9gOY2vEyCBn8ozjh4ysr+TjOJv6RhS/9krIH9ULmGM6oqUuKoUQ/yzsVU+PHvFVNu afn6+2dKl5frmjFmlWcojpkcEP3SWamWJayIQLw8W5BX8TUu12OvPEr6EEZMsqTb1y6y LLFg== X-Gm-Message-State: ALKqPwd6efkKZl+QVZn8Xgx+f+r9UG9dD/QnCAcgVWsxYfbUHvrUqTG4 sw/Prirc1fQIV4/Z9QVCPb1kw4hVKrfZusCt+8lL5eC7JLt5a7JiMRNSxcrw/xScc/Oe2cz6uKe 9L2CPWxbfu7Bo1lwl1/jnBzzAj5GS7Nk8/zcOwkue+0GjUn5L1ayATD4p4dr6NKg= X-Received: by 2002:a17:902:a717:: with SMTP id w23-v6mr10220398plq.130.1526662118719; Fri, 18 May 2018 09:48:38 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpgn2PDZ7vga4t8Q3XYrO1CfdSBPumgAcpFjr4QIPsT6AR73FDIBkY48ex4+Qoq/OLcYi/F X-Received: by 2002:a17:902:a717:: with SMTP id w23-v6mr10220344plq.130.1526662117732; Fri, 18 May 2018 09:48:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526662117; cv=none; d=google.com; s=arc-20160816; b=0PQQ2h4S47goH8wg1L7FwNFKGmX/xiRr+TpIhzDQyROQyzkHsHBVuJSzSkPK1rzbBW DaklQmqQfQ3uXFNHhdETVsP2lBHGsHhwkPmckFl5NX5zuEBpf+7sUHmFC/nB/idBTfZu dR3lMSRf6jNkcLOjMheqg7KZFz0WU2gRn6uVDDzEE/xU+P4tV9mYRc1iWzQTDAJbCij3 RPHP7zkDO/6z+2SgikkK46JhNfzA+dEo/SLGqAUgXyMxY0/5M9C2c8dBx0DEB6Vs+5lt 1xD2hhbYmqrVNHDmru4JK6fHYRs2tXfqxpRyTPhkz47XsWy8l0/pYxx3bAI0DzKfib8C G6Vg== 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=m9e7LyI0Hb29RdOx1TgmifyTpn9WHrmJ6NNaZ6XE5/E=; b=LRAqcpjBuoj+vbqwQP73gQ0cqIVgjxBXJMpfOVq5ddXpJsq/JKdDbq9B5ySp4uDZ+1 By13mhIJtWaz2I4HLs1cndcOg9NgYlgO0mJDE3a4NI+VyrbqBR5ZlnxwErUW1pDXTat1 iXad0fK2OIG5P7ETDekOjnmfnpmlby4t5dgTDd1AFwgSGk2w+mcbAt0o5OnlNeYKEubn DJ4Ar1+ONmeN94vcVjeJdfzWMcsWX+by9oxeTuwiA1S+E0TDKuSQA+PK/qtEZX6MyGqy LhwXkfcImcdl5KESy6Zxeps3uBXGkTe3gyhDdduPkfohFwYW4Pu9f9uAv0CyUEKo0/Yc kH1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@infradead.org header.s=bombadil.20170209 header.b=srglhh3l; spf=pass (google.com: best guess record for domain of batv+77ddf8e9b1b344f28472+5381+infradead.org+hch@bombadil.srs.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom=BATV+77ddf8e9b1b344f28472+5381+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 o185-v6si6468064pga.274.2018.05.18.09.48.37 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 18 May 2018 09:48:37 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of batv+77ddf8e9b1b344f28472+5381+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=srglhh3l; spf=pass (google.com: best guess record for domain of batv+77ddf8e9b1b344f28472+5381+infradead.org+hch@bombadil.srs.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom=BATV+77ddf8e9b1b344f28472+5381+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=m9e7LyI0Hb29RdOx1TgmifyTpn9WHrmJ6NNaZ6XE5/E=; b=srglhh3l6n4B3/mstoeDA4AqK N/PoNGOzPwf8icX3po86JsQXCq0vOg4gp3lBDOF8vcD5xCYfEG+6bQzO9E34PGiNa6Sq0OTMSLYwp cjCUA2MIgMef1lsXwSDeiMD1086F2IvHD4gwTuoo7cI2Q0yj1c2PcaCourg2B5ZPyNpF/ZEoAo2yK tDvSYQ+7zgx5Z+0ne5vBF4sJq09QArQYR6h3iQ3s871yowmOzjjnbbwbi8Lf745TrLKlom9GM36pr tArUSB5W07vTzO6tYnUy5fiP3DY9yTqXI3/QqIhcwENk1Bn8YnW3YuroN5xOU3KYL2/LJR0L2imdp g1re6sufQ==; Received: from 80-109-164-210.cable.dynamic.surfer.at ([80.109.164.210] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1fJiYW-0006Rl-R3; Fri, 18 May 2018 16:48:37 +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/34] block: add a lower-level bio_add_page interface Date: Fri, 18 May 2018 18:47:57 +0200 Message-Id: <20180518164830.1552-2-hch@lst.de> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180518164830.1552-1-hch@lst.de> References: <20180518164830.1552-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 Reviewed-by: Jens Axboe --- block/bio.c | 96 +++++++++++++++++++++++++++++---------------- include/linux/bio.h | 9 +++++ 2 files changed, 72 insertions(+), 33 deletions(-) diff --git a/block/bio.c b/block/bio.c index 53e0f0a1ed94..fdf635d42bbd 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; /* @@ -821,52 +821,82 @@ int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page EXPORT_SYMBOL(bio_add_pc_page); /** - * bio_add_page - attempt to add page to bio - * @bio: destination bio - * @page: page to add - * @len: vec entry length - * @offset: vec entry offset + * __bio_try_merge_page - try appending data to an existing bvec. + * @bio: destination bio + * @page: page to add + * @len: length of the data to add + * @off: offset of the data in @page * - * Attempt to add a page to the bio_vec maplist. This will only fail - * if either bio->bi_vcnt == bio->bi_max_vecs or it's a cloned bio. + * Try to add the data at @page + @off to the last bvec of @bio. This is a + * a useful optimisation for file systems with a block size smaller than the + * page size. + * + * Return %true on success or %false on failure. */ -int bio_add_page(struct bio *bio, struct page *page, - unsigned int len, unsigned int offset) +bool __bio_try_merge_page(struct bio *bio, struct page *page, + unsigned int len, unsigned int off) { - struct bio_vec *bv; - - /* - * cloned bio must not modify vec list - */ if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED))) - return 0; + return false; - /* - * 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]; + struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1]; - if (page == bv->bv_page && - offset == bv->bv_offset + bv->bv_len) { + if (page == bv->bv_page && off == bv->bv_offset + bv->bv_len) { bv->bv_len += len; - goto done; + bio->bi_iter.bi_size += len; + return true; } } + return false; +} +EXPORT_SYMBOL_GPL(__bio_try_merge_page); - if (bio->bi_vcnt >= bio->bi_max_vecs) - return 0; +/** + * __bio_add_page - add page to a bio in a new segment + * @bio: destination bio + * @page: page to add + * @len: length of the data to add + * @off: offset of the data in @page + * + * Add the data at @page + @off 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]; - bv = &bio->bi_io_vec[bio->bi_vcnt]; - bv->bv_page = page; - bv->bv_len = len; - bv->bv_offset = offset; + WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)); + WARN_ON_ONCE(bio_full(bio)); + + bv->bv_page = page; + bv->bv_offset = off; + bv->bv_len = len; - bio->bi_vcnt++; -done: 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 + * @page: page to add + * @len: vec entry length + * @offset: vec entry offset + * + * Attempt to add a page to the bio_vec maplist. This will only fail + * if either bio->bi_vcnt == bio->bi_max_vecs or it's a cloned bio. + */ +int bio_add_page(struct bio *bio, struct page *page, + unsigned int len, unsigned int offset) +{ + if (!__bio_try_merge_page(bio, page, len, offset)) { + if (bio_full(bio)) + return 0; + __bio_add_page(bio, page, len, offset); + } 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 *,