From patchwork Fri Oct 20 02:39:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 10018779 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 0E02B60234 for ; Fri, 20 Oct 2017 02:46:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EEA8F28E8B for ; Fri, 20 Oct 2017 02:46:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E358928E8E; Fri, 20 Oct 2017 02:46:05 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI 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 8D5BA28E8B for ; Fri, 20 Oct 2017 02:46:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751976AbdJTCqD (ORCPT ); Thu, 19 Oct 2017 22:46:03 -0400 Received: from mga02.intel.com ([134.134.136.20]:17993 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751990AbdJTCqC (ORCPT ); Thu, 19 Oct 2017 22:46:02 -0400 Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Oct 2017 19:46:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,404,1503385200"; d="scan'208";a="164817724" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.125]) by fmsmga005.fm.intel.com with ESMTP; 19 Oct 2017 19:45:59 -0700 Subject: [PATCH v3 07/13] dax: warn if dma collides with truncate From: Dan Williams To: akpm@linux-foundation.org Cc: Jan Kara , Matthew Wilcox , linux-nvdimm@lists.01.org, linux-kernel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-mm@kvack.org, Jeff Moyer , linux-fsdevel@vger.kernel.org, Ross Zwisler , hch@lst.de Date: Thu, 19 Oct 2017 19:39:34 -0700 Message-ID: <150846717482.24336.5408601305480590234.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <150846713528.24336.4459262264611579791.stgit@dwillia2-desk3.amr.corp.intel.com> References: <150846713528.24336.4459262264611579791.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.17.1-9-g687f MIME-Version: 1.0 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Catch cases where truncate encounters pages that are still under active dma. This warning is a canary for potential data corruption as truncated blocks could be allocated to a new file while the device is still perform i/o. Cc: Jan Kara Cc: Jeff Moyer Cc: Christoph Hellwig Cc: Matthew Wilcox Cc: Ross Zwisler Signed-off-by: Dan Williams --- fs/dax.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/dax.c b/fs/dax.c index ac6497dcfebd..b03f547b36e7 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -437,6 +437,38 @@ static void *grab_mapping_entry(struct address_space *mapping, pgoff_t index, return entry; } +static unsigned long dax_entry_size(void *entry) +{ + if (dax_is_zero_entry(entry)) + return 0; + else if (dax_is_pmd_entry(entry)) + return HPAGE_SIZE; + else + return PAGE_SIZE; +} + +static void dax_check_truncate(void *entry) +{ + unsigned long pfn = dax_radix_pfn(entry); + unsigned long size = dax_entry_size(entry); + unsigned long end_pfn; + + if (!size) + return; + end_pfn = pfn + size / PAGE_SIZE; + for (; pfn < end_pfn; pfn++) { + struct page *page = pfn_to_page(pfn); + + /* + * devmap pages are idle when their count is 1 and the + * only path that increases their count is + * get_user_pages(). + */ + WARN_ONCE(page_ref_count(page) > 1, + "dax-dma truncate collision\n"); + } +} + static int __dax_invalidate_mapping_entry(struct address_space *mapping, pgoff_t index, bool trunc) { @@ -452,6 +484,7 @@ static int __dax_invalidate_mapping_entry(struct address_space *mapping, (radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_DIRTY) || radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_TOWRITE))) goto out; + dax_check_truncate(entry); radix_tree_delete(page_tree, index); mapping->nrexceptional--; ret = 1;