From patchwork Thu Nov 19 00:22:14 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 7653651 Return-Path: X-Original-To: patchwork-linux-nvdimm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id F412BBF90C for ; Thu, 19 Nov 2015 00:22:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 17CA2205AA for ; Thu, 19 Nov 2015 00:22:38 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F37B12055C for ; Thu, 19 Nov 2015 00:22:36 +0000 (UTC) Received: from ml01.vlan14.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id C2C711A209A; Wed, 18 Nov 2015 16:22:36 -0800 (PST) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by ml01.01.org (Postfix) with ESMTP id D37C01A209A for ; Wed, 18 Nov 2015 16:22:35 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 18 Nov 2015 16:22:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,315,1444719600"; d="scan'208";a="823588081" Received: from orsmsx102.amr.corp.intel.com ([10.22.225.129]) by orsmga001.jf.intel.com with ESMTP; 18 Nov 2015 16:22:15 -0800 Received: from orsmsx151.amr.corp.intel.com (10.22.226.38) by ORSMSX102.amr.corp.intel.com (10.22.225.129) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 18 Nov 2015 16:22:15 -0800 Received: from orsmsx107.amr.corp.intel.com ([169.254.1.20]) by ORSMSX151.amr.corp.intel.com ([169.254.7.146]) with mapi id 14.03.0248.002; Wed, 18 Nov 2015 16:22:14 -0800 From: "Williams, Dan J" To: "jack@suse.cz" Subject: Re: [PATCH 4/8] mm, dax: truncate dax mappings at bdev or fs shutdown Thread-Topic: [PATCH 4/8] mm, dax: truncate dax mappings at bdev or fs shutdown Thread-Index: AQHRIXTl8iZqnmv7nE29j98RravwXZ6iaYOAgACaXIA= Date: Thu, 19 Nov 2015 00:22:14 +0000 Message-ID: <1447892533.13153.8.camel@intel.com> References: <20151117201551.15053.32709.stgit@dwillia2-desk3.jf.intel.com> <20151117201614.15053.62376.stgit@dwillia2-desk3.jf.intel.com> <20151118150945.GE6097@quack.suse.cz> In-Reply-To: <20151118150945.GE6097@quack.suse.cz> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.7.201.19] Content-ID: <6B6D0922B2EF4F43A9FF42B705D0E9AC@intel.com> MIME-Version: 1.0 Cc: "linux-nvdimm@lists.01.org" , "david@fromorbit.com" , "stable@vger.kernel.org" , "linux-block@vger.kernel.org" , "jack@suse.com" , "linux-fsdevel@vger.kernel.org" , "akpm@linux-foundation.org" X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Spam-Status: No, score=-3.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Wed, 2015-11-18 at 16:09 +0100, Jan Kara wrote: > Hum, I don't get this. truncate_inode_pages_final() gets called when inode > has no more users. So there are no mappings of the inode. So how could > truncate_pagecache() possibly make a difference? True.  I confirmed with more focus testing that the change to truncate_inode_pages_final() is not necessary.  After invalidate_inodes() does unmap_mapping_range() we are protected by future calls to get_block() and blk_queue_enter() failing when there are attempts to re-establish a mapping after the block device has been torn down. Here's a revised patch.  Note that the call truncate_pagecache() is replaced with a call to unmap_mapping_range() since it is fine to access zero pages that might still be in the page cache. 8<---- Subject: mm, dax: unmap dax mappings at bdev or fs shutdown From: Dan Williams Currently dax mappings leak past / survive block_device shutdown.  While page cache pages are permitted to be read/written after the block_device is torn down this is not acceptable in the dax case as all media access must end when the device is disabled.  The pfn backing a dax mapping is permitted to be invalidated after bdev shutdown and this is indeed the case with brd. When a dax capable block_device driver calls del_gendisk() in its shutdown path del_gendisk() needs to ensure that all DAX pfns are unmapped.  This is different than the pagecache backed case where the disk is protected by the queue being torn down which ends I/O to the device.  Since dax bypasses the page cache we need to unconditionally unmap the inode. Cc: Cc: Jan Kara Cc: Dave Chinner Cc: Matthew Wilcox Cc: Ross Zwisler [honza: drop changes to truncate_inode_pages_final] Signed-off-by: Dan Williams ---  fs/inode.c |   27 +++++++++++++++++++++++++++  1 file changed, 27 insertions(+) diff --git a/fs/inode.c b/fs/inode.c index 1be5f9003eb3..dcb31d2c15e6 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -579,6 +579,18 @@ static void dispose_list(struct list_head *head)   }  }   +static void unmap_list(struct list_head *head) +{ + struct inode *inode, *_i; + + list_for_each_entry_safe(inode, _i, head, i_lru) { + list_del_init(&inode->i_lru); + unmap_mapping_range(&inode->i_data, 0, 0, 1); + iput(inode); + cond_resched(); + } +} +  /**   * evict_inodes - evict all evictable inodes for a superblock   * @sb: superblock to operate on @@ -642,6 +654,7 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)   int busy = 0;   struct inode *inode, *next;   LIST_HEAD(dispose); + LIST_HEAD(unmap);     spin_lock(&sb->s_inode_list_lock);   list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) { @@ -655,6 +668,19 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)   busy = 1;   continue;   } + if (IS_DAX(inode) && atomic_read(&inode->i_count)) { + /* +  * dax mappings can't live past this invalidation event +  * as there is no page cache present to allow the data +  * to remain accessible. +  */ + __iget(inode); + inode_lru_list_del(inode); + spin_unlock(&inode->i_lock); + list_add(&inode->i_lru, &unmap); + busy = 1; + continue; + }   if (atomic_read(&inode->i_count)) {   spin_unlock(&inode->i_lock);   busy = 1; @@ -669,6 +695,7 @@ int invalidate_inodes(struct super_block *sb, bool kill_dirty)   spin_unlock(&sb->s_inode_list_lock);     dispose_list(&dispose); + unmap_list(&unmap);     return busy;  }