From patchwork Tue Dec 27 16:04:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 9489467 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 624E562AAD for ; Tue, 27 Dec 2016 16:05:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5487D201BC for ; Tue, 27 Dec 2016 16:05:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 49670223B2; Tue, 27 Dec 2016 16:05:50 +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.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID 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 E6846201BC for ; Tue, 27 Dec 2016 16:05:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932373AbcL0QFn (ORCPT ); Tue, 27 Dec 2016 11:05:43 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:32797 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755589AbcL0QFf (ORCPT ); Tue, 27 Dec 2016 11:05:35 -0500 Received: by mail-pg0-f67.google.com with SMTP id g1so12809221pgn.0; Tue, 27 Dec 2016 08:05:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1KEgcAG8XnJiIm5QCwxm0Ygs9cb3FVNxcJaiAsiJeeg=; b=XCF6bAz3FBP88GMcMYBFDyf8Y3VlE5FXGmh4Siwq3yPtbPr2D+REgOlNjcMNlZv/K0 nQgWmGocpBQz3Ql8n/YsTzfj3U6NG588gvFkjgZ8wUYKShkPUO/PoKfqJvSrYcbw3e6D gmlW4elnJDYPmTrv5Ig5U1J5d2tFjyNgwJ2A90xu/eE+cTKwn/NK3Ab9lYOuc8xLFi14 tVnRbqkVTdJv3h20y0Ki8bODZPDv7KmD/7DtrzS+Mn+HVwakr3fKDK1jvyU6rpq3gZv7 L7JKmFcG4l0ae9fBCULI2seIAFVfqCSPx2+8Ttn6KSSVci/ejCqw9ID89Hh4H1epMwKQ hfqw== 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:in-reply-to :references; bh=1KEgcAG8XnJiIm5QCwxm0Ygs9cb3FVNxcJaiAsiJeeg=; b=AxX6G8XIwPp80ugMlRMEM1VW5Hi7pHuBnHrdGvHgM5b4goSQTqOFFRwx89ylQ05U8Y ZuVCYn/h0jSGwmKT6HMzyLjnRxx61l2QREPTdCd+zus/ui/swXvj6mI5Nep0XA7NYBt0 pn0WAOAgsmpA5tZj9TeeSqtgE6mGOFYe9yN14yjB3c+8ls/nogdoVDE9XU6gaCkB9oLC njJadPnf0k/CU6SHINtyEMcPB5Z6GNOw05IaJ0JKqZInHramETW3UqA+Ltij6iB+vfQI oFgZLqgH5JmLkDv7f+2zq+XvF6x3HJUPyvBRDiLCZ1myXHKRyK7Kwx/9GMe5K3/738o/ dcJQ== X-Gm-Message-State: AIkVDXLky4pSU5x/t12J0JPv46wA4I1Md0pLQ/I918JjxxqdAujiRWrlZ7PO283Jmkh4og== X-Received: by 10.98.78.88 with SMTP id c85mr30316760pfb.138.1482854734670; Tue, 27 Dec 2016 08:05:34 -0800 (PST) Received: from localhost ([45.35.47.137]) by smtp.gmail.com with ESMTPSA id a22sm90675224pfg.7.2016.12.27.08.05.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Dec 2016 08:05:33 -0800 (PST) From: Ming Lei To: Jens Axboe , linux-kernel@vger.kernel.org Cc: linux-block@vger.kernel.org, Christoph Hellwig , Ming Lei , Jens Axboe Subject: [PATCH v1 33/54] block: deal with dirtying pages for multipage bvec Date: Wed, 28 Dec 2016 00:04:42 +0800 Message-Id: <1482854706-14128-2-git-send-email-tom.leiming@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1482854706-14128-1-git-send-email-tom.leiming@gmail.com> References: <1482854706-14128-1-git-send-email-tom.leiming@gmail.com> 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 In bio_check_pages_dirty(), bvec->bv_page is used as flag for marking if the page has been dirtied & released, and if no, it will be dirtied in deferred workqueue. With multipage bvec, we can't do that any more, so change the logic into checking all pages in one mp bvec, and only release all these pages if all are dirtied, otherwise dirty them all in deferred wrokqueue. Signed-off-by: Ming Lei --- block/bio.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/block/bio.c b/block/bio.c index a76ed8a780de..e65de53acb9f 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1655,8 +1655,9 @@ void bio_set_pages_dirty(struct bio *bio) { struct bio_vec *bvec; int i; + struct bvec_iter_all bia; - bio_for_each_segment_all(bvec, bio, i) { + bio_for_each_segment_all_sp(bvec, bio, i, bia) { struct page *page = bvec->bv_page; if (page && !PageCompound(page)) @@ -1664,16 +1665,26 @@ void bio_set_pages_dirty(struct bio *bio) } } +static inline void release_mp_bvec_pages(struct bio_vec *bvec) +{ + struct bio_vec bv; + struct bvec_iter iter; + + bvec_for_each_sp_bvec(bv, bvec, iter) + put_page(bv.bv_page); +} + static void bio_release_pages(struct bio *bio) { struct bio_vec *bvec; int i; - bio_for_each_segment_all(bvec, bio, i) { + /* iterate each mp bvec */ + bio_for_each_segment_all_mp(bvec, bio, i) { struct page *page = bvec->bv_page; if (page) - put_page(page); + release_mp_bvec_pages(bvec); } } @@ -1717,20 +1728,38 @@ static void bio_dirty_fn(struct work_struct *work) } } +static inline void check_mp_bvec_pages(struct bio_vec *bvec, + int *nr_dirty, int *nr_pages) +{ + struct bio_vec bv; + struct bvec_iter iter; + + bvec_for_each_sp_bvec(bv, bvec, iter) { + struct page *page = bv.bv_page; + + if (PageDirty(page) || PageCompound(page)) + (*nr_dirty)++; + (*nr_pages)++; + } +} + void bio_check_pages_dirty(struct bio *bio) { struct bio_vec *bvec; int nr_clean_pages = 0; int i; - bio_for_each_segment_all(bvec, bio, i) { - struct page *page = bvec->bv_page; + bio_for_each_segment_all_mp(bvec, bio, i) { + int nr_dirty = 0, nr_pages = 0; + + check_mp_bvec_pages(bvec, &nr_dirty, &nr_pages); - if (PageDirty(page) || PageCompound(page)) { - put_page(page); + /* release all pages in the mp bvec if all are dirtied */ + if (nr_dirty == nr_pages) { + release_mp_bvec_pages(bvec); bvec->bv_page = NULL; } else { - nr_clean_pages++; + nr_clean_pages += nr_pages; } }