From patchwork Thu May 31 18:06:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 10441643 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 D8032602BC for ; Thu, 31 May 2018 18:06:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C64CA28F25 for ; Thu, 31 May 2018 18:06:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BAE3228FA7; Thu, 31 May 2018 18:06:30 +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 AD5F728F25 for ; Thu, 31 May 2018 18:06:29 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 9A98B6B0007; Thu, 31 May 2018 14:06:28 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 957346B0008; Thu, 31 May 2018 14:06:28 -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 7AA3F6B000A; Thu, 31 May 2018 14:06:28 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf0-f200.google.com (mail-pf0-f200.google.com [209.85.192.200]) by kanga.kvack.org (Postfix) with ESMTP id 37B7D6B0007 for ; Thu, 31 May 2018 14:06:28 -0400 (EDT) Received: by mail-pf0-f200.google.com with SMTP id w14-v6so7578796pfn.12 for ; Thu, 31 May 2018 11:06:28 -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=7vl0Wsl7F7JfrvB1OH7iRnM23EWZ55bgWqX/lo0FSLU=; b=REcVgdX3ZIkeHvCsPUe7sjXyvZfr8Uj2zX6M73q3iR2gZY7CpkThRJYkhAPi76JUrF pJSzmLY+LMgaWO8WdM52CLeg+lR2wwC0K0nhNqZzRVl29tDmNkKtKDcQkHg5GM2vYj5S sELtiPf9ufhHtc4wS+0LyHro5+Ze/VODckhaG5CtaSBgBdJbjqWy/jpDBUSyBn/7fDQC uQdZ9J0qffIgyNBz4N3XqMR9j5v2BIs+wcb266Rb6IhnK82z2jAwvC43YZ5Pp1HWSQQG B7cMpQhhOr69sJYDveTRYn6Zrj9lbifkcXosPdT7iDgsvaixcQSnKShCD87DZKdkuBRb 5EBQ== X-Gm-Message-State: ALKqPwdHSYuneoHcnhffakVk5MTbgkAVb/zp50lmSUcncofLWcVNclN7 hExLIoBoX9y3eK3kyLAi2C1JQRzAlggQrqiFGBykUWgrrq3n/7YkEjeF+lghPTsYT4ZQ0Ygv2Lt 8MbZ7Ae2K33krlXP7ols4OnW9dAyAw3mHN516ESO0ruXBuS/TXSSnAKCh04PKYbo= X-Received: by 2002:a17:902:b611:: with SMTP id b17-v6mr7891960pls.284.1527789987890; Thu, 31 May 2018 11:06:27 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIsMCpM4Ql8ZVSCfZyrqiTet2uPrZtpdXDEbu2zEGSUz+tTVWgyZ944TeL8D+aW58GQMCuM X-Received: by 2002:a17:902:b611:: with SMTP id b17-v6mr7891831pls.284.1527789985156; Thu, 31 May 2018 11:06:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527789985; cv=none; d=google.com; s=arc-20160816; b=sEB0Y1wsbwRbCYSO4QpWx1yzftKD7FNN3aTjloZ0S5o576sNHdfancf6bwq6sgUpMS 7g5vP7gUZChCIS2HTT0LNKokRgayYsBvIKh2j2jJSR0iYAL+E+mCSaD/dItwGtbDG51x bAj2DKan9ta3C5auhiDl4k+c0dZMrS6DWV6qKY6rO9R/8TgDFQtvqo3V6E/LAvRhiqKJ BcqvDrWWOjWGb5MQUkW5zSdOE+HwnRtb/WJJ+VNhERMDeua9fmw63tKxqCPl8vWP15tV frfSagEUUpoxOdOljTqKkO5oWBD6QVPeu5OH/R/z122OP0I5ksT8+h45/B47LDp4Zx1F PyMA== 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=7vl0Wsl7F7JfrvB1OH7iRnM23EWZ55bgWqX/lo0FSLU=; b=pGAlnIB3J2bJtMDe5uyH1H4T5C8H/Kh9DJuwpxhpyPExrbIg+qPalQ1bFYZpwxYkSh MTE5jc90NCWcz7zcWOLgsV/Qzvm5meZnDb7uqseaUijYWw2/ccbKmO85cxw7xXSMBnro zsa2BpJVkDMLmRCVht/yt6R7EWJ7QIrlBEKcVXnH69EaK+e4RKzK7FjKFQzpr2XB21YB 7A4LE7pwfU+vpii4vwJmggTabineCg4BtrkhT7qqvkuhtQnQVU6bNN6Fj7kZMcZbclGS ZlvMMqa8qKtkcXrkAjF/Q9deERuiGp17Wb4zEQwswaVuZ2FwmXkndY6kbtXK6s/zlTog RHwA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@infradead.org header.s=bombadil.20170209 header.b=Qmgg9pUE; spf=pass (google.com: best guess record for domain of batv+67dfbb8f664e29ec4bbc+5394+infradead.org+hch@bombadil.srs.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom=BATV+67dfbb8f664e29ec4bbc+5394+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 w68-v6si37677125pfb.325.2018.05.31.11.06.24 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 11:06:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of batv+67dfbb8f664e29ec4bbc+5394+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=Qmgg9pUE; spf=pass (google.com: best guess record for domain of batv+67dfbb8f664e29ec4bbc+5394+infradead.org+hch@bombadil.srs.infradead.org designates 2607:7c80:54:e::133 as permitted sender) smtp.mailfrom=BATV+67dfbb8f664e29ec4bbc+5394+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=7vl0Wsl7F7JfrvB1OH7iRnM23EWZ55bgWqX/lo0FSLU=; b=Qmgg9pUELqPsmMO9ExJ+Ddg4l 4yxs/OK7li8sqX0DfF96t6NKlKzvw55mMBlwTwmbF7Ms72PU/s0Ju/lrqlYZNqDlm59UK9QxRaLO3 qqXz6Hh6tmFkUBsyOCZwBVKJtSdW6RfATHlL9DjxR1IrjLi+aeYPI4W4SvZ69UQ4r8YDVJ7FjXKla zrxng/Q+PPvhR2Rfs1R0T4IwecnpGFx41dAmA2C2zF0iLiTHkpM6jmL5V6OKmv9fgL6tVKHyPo1WX 13wL0P46Rzeu8eQTTYi3Lv/W2o8WjaHbiEf23QTjhawT/fvTv//zWhGeb/yaSCF2X5arYxybVo94D 0BgvaVtWg==; Received: from 213-225-38-123.nat.highway.a1.net ([213.225.38.123] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.90_1 #2 (Red Hat Linux)) id 1fORxs-0003AS-Hu; Thu, 31 May 2018 18:06:20 +0000 From: Christoph Hellwig To: linux-xfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH 01/13] block: add a lower-level bio_add_page interface Date: Thu, 31 May 2018 20:06:02 +0200 Message-Id: <20180531180614.21506-2-hch@lst.de> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180531180614.21506-1-hch@lst.de> References: <20180531180614.21506-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 Reviewed-by: Ming Lei Reviewed-by: Darrick J. Wong --- 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 *,