From patchwork Sat Oct 29 08:08:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ming Lei X-Patchwork-Id: 9403303 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 305F160587 for ; Sat, 29 Oct 2016 08:21:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1CDD229D23 for ; Sat, 29 Oct 2016 08:21:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 115512A5D7; Sat, 29 Oct 2016 08:21:16 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable 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 BBCEB29D23 for ; Sat, 29 Oct 2016 08:21:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966262AbcJ2IPg (ORCPT ); Sat, 29 Oct 2016 04:15:36 -0400 Received: from mail-pf0-f194.google.com ([209.85.192.194]:33989 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966258AbcJ2IPc (ORCPT ); Sat, 29 Oct 2016 04:15:32 -0400 Received: by mail-pf0-f194.google.com with SMTP id u84so3381955pfj.1; Sat, 29 Oct 2016 01:15:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=HMfZj9DBcgkVkUDX13im3NTSs4EDVdj5y4Nb2c2XMYA=; b=Id0QvR6tGem19K4u7IrkVCyztcIBSQkDpSLkrjOT6Zd/XUUt4viEUWBmqLPuLy5Dmz 5ECf7nOWSTMJlD4wujfuNJSg+u+zWJDFkd6Cp2b2SXXpksiQnXXUCof1feYjRJpa5zBA 0Ig1+8tK82+tn9bvYCm4kT7IFzKC4JvHvt5kRlZALZqKLsKKfTkF+wDEFdxhGRoXMFxy PkGd6fsDmazRd8aGuAQd1kVnNKbs03b6KTKYyDgOcfi0nNPqty669Kqv3dYuTD9Eixlk cTbEy7BxNGP/g75JZx92Zz3a29KlBDC8mOtaZLV04SEgQh42UqvNlJs4mYlZeaEyCGFw +L7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=HMfZj9DBcgkVkUDX13im3NTSs4EDVdj5y4Nb2c2XMYA=; b=Mag0RScWAuh1uBOPUUVfq89BdMHN6xtavGgKPPR95qETDQZ3PLAy7l9IAzFmivTJj3 /CzxExis8dsnqYQVAObCDlgvGru1atLIncQ6BYM5dNyIf+sEz92/p2fIOVcW+YcZdHoa Ez6I0tidXzHST1gHtZVI0VrkTJ7fZ2VQIG4w3fllMxdp74l6yYh5W8Yt2rZeVWnm3alD 0NLhhfQUPGR94uKiX02yqH7ubbgAELBZi5ND06LdBeqW8UPerbo3idsXIXmvFaeqoxI/ vsOF6dJ/vYVcwwlpdKRacPNahjGy2Hlqo43vfPxjFxKYwq+cGakReClG3bPyEFPEPWp6 RFrg== X-Gm-Message-State: ABUngvflyEmWpx2JyDK7tr8oyOSmZ0IxyPKSJOfD7n4CRrvJQ8mPUYOoG+96kPmPqxbBdg== X-Received: by 10.98.108.4 with SMTP id h4mr31590290pfc.11.1477728932014; Sat, 29 Oct 2016 01:15:32 -0700 (PDT) Received: from localhost ([45.34.23.101]) by smtp.gmail.com with ESMTPSA id 13sm2593824pfz.72.2016.10.29.01.15.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 29 Oct 2016 01:15:31 -0700 (PDT) From: Ming Lei To: Jens Axboe , linux-kernel@vger.kernel.org Cc: linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org, Christoph Hellwig , "Kirill A . Shutemov" , Ming Lei , Jens Axboe Subject: [PATCH 46/60] block: deal with dirtying pages for multipage bvec Date: Sat, 29 Oct 2016 16:08:45 +0800 Message-Id: <1477728600-12938-47-git-send-email-tom.leiming@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1477728600-12938-1-git-send-email-tom.leiming@gmail.com> References: <1477728600-12938-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 | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/block/bio.c b/block/bio.c index a9bf01784f37..8e5af6e8bba3 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1597,8 +1597,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_rd(bvec, bio, i, bia) { struct page *page = bvec->bv_page; if (page && !PageCompound(page)) @@ -1606,16 +1607,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; + /* iterate each mp bvec */ bio_for_each_segment_all(bvec, bio, i) { struct page *page = bvec->bv_page; if (page) - put_page(page); + release_mp_bvec_pages(bvec); } } @@ -1659,20 +1670,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_wt(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; } }