From patchwork Fri Jan 20 03:51:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 9527305 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 062CE60434 for ; Fri, 20 Jan 2017 03:55:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA9B228639 for ; Fri, 20 Jan 2017 03:55:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DF6AD2866A; Fri, 20 Jan 2017 03:55:55 +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 82B692864F for ; Fri, 20 Jan 2017 03:55:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751681AbdATDzZ (ORCPT ); Thu, 19 Jan 2017 22:55:25 -0500 Received: from mga05.intel.com ([192.55.52.43]:8145 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751669AbdATDzY (ORCPT ); Thu, 19 Jan 2017 22:55:24 -0500 Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga105.fm.intel.com with ESMTP; 19 Jan 2017 19:55:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,257,1477983600"; d="scan'208";a="55445708" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.14]) by fmsmga005.fm.intel.com with ESMTP; 19 Jan 2017 19:55:23 -0800 Subject: [PATCH 12/13] libnvdimm, pmem: disable dax flushing when pmem is fronting a volatile region From: Dan Williams To: linux-nvdimm@lists.01.org Cc: Jan Kara , Matthew Wilcox , linux-kernel@vger.kernel.org, Jeff Moyer , linux-fsdevel@vger.kernel.org, Ross Zwisler , Christoph Hellwig Date: Thu, 19 Jan 2017 19:51:17 -0800 Message-ID: <148488427774.37913.13035450429562766439.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <148488421301.37913.12835362165895864897.stgit@dwillia2-desk3.amr.corp.intel.com> References: <148488421301.37913.12835362165895864897.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.17.1-9-g687f MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The pmem driver attaches to both persistent and volatile memory ranges advertised by the ACPI NFIT. When the region is volatile it is redundant to spend cycles flushing caches at fsync(). Check if the hosting region is volatile and do not publish a ->flush() dax method if so. Cc: Jan Kara Cc: Jeff Moyer Cc: Christoph Hellwig Cc: Matthew Wilcox Cc: Ross Zwisler Signed-off-by: Dan Williams --- drivers/nvdimm/pmem.c | 31 ++++++++++++++++++++++++++----- drivers/nvdimm/region_devs.c | 8 ++++++-- 2 files changed, 32 insertions(+), 7 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" 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/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 47392c4f22b9..53b7e4eb9d92 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -229,6 +229,17 @@ static const struct block_device_operations pmem_fops = { .dax_ops = &pmem_dax_ops, }; +static const struct dax_operations vmem_dax_ops = { + .direct_access = pmem_direct_access, +}; + +static const struct block_device_operations vmem_fops = { + .owner = THIS_MODULE, + .rw_page = pmem_rw_page, + .revalidate_disk = nvdimm_revalidate_disk, + .dax_ops = &vmem_dax_ops, +}; + static void pmem_release_queue(void *q) { blk_cleanup_queue(q); @@ -254,6 +265,7 @@ static int pmem_attach_disk(struct device *dev, struct resource pfn_res; struct request_queue *q; struct gendisk *disk; + int has_flush; void *addr; /* while nsio_rw_bytes is active, parse a pfn info block if present */ @@ -274,7 +286,8 @@ static int pmem_attach_disk(struct device *dev, dev_set_drvdata(dev, pmem); pmem->phys_addr = res->start; pmem->size = resource_size(res); - if (nvdimm_has_flush(nd_region) < 0) + has_flush = nvdimm_has_flush(nd_region); + if (has_flush == -ENXIO) dev_warn(dev, "unable to guarantee persistence of writes\n"); if (!devm_request_mem_region(dev, res->start, resource_size(res), @@ -316,7 +329,12 @@ static int pmem_attach_disk(struct device *dev, return PTR_ERR(addr); pmem->virt_addr = addr; - blk_queue_write_cache(q, true, true); + /* + * If the region is !volatile request that the upper layers send + * flush requests to trigger fencing and wpq flushing + */ + if (has_flush != -EINVAL) + blk_queue_write_cache(q, true, true); blk_queue_make_request(q, pmem_make_request); blk_queue_physical_block_size(q, PAGE_SIZE); blk_queue_max_hw_sectors(q, UINT_MAX); @@ -329,9 +347,12 @@ static int pmem_attach_disk(struct device *dev, if (!disk) return -ENOMEM; - disk->fops = &pmem_fops; - disk->queue = q; - disk->flags = GENHD_FL_EXT_DEVT; + if (has_flush == -EINVAL) + disk->fops = &vmem_fops; + else + disk->fops = &pmem_fops; + disk->queue = q; + disk->flags = GENHD_FL_EXT_DEVT; nvdimm_namespace_disk_name(ndns, disk->disk_name); set_capacity(disk, (pmem->size - pmem->pfn_pad - pmem->data_offset) / 512); diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 6945df8a3367..ef32b938023e 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -953,15 +953,19 @@ EXPORT_SYMBOL_GPL(nvdimm_flush); * nvdimm_has_flush - determine write flushing requirements * @nd_region: blk or interleaved pmem region * - * Returns 1 if writes require flushing - * Returns 0 if writes do not require flushing + * Returns 1 if writes require wpq flushing + * Returns 0 if writes do not require wpq flushing * Returns -ENXIO if flushing capability can not be determined + * Returns -EINVAL if neither wpq nor cache flushing is required */ int nvdimm_has_flush(struct nd_region *nd_region) { struct nd_region_data *ndrd = dev_get_drvdata(&nd_region->dev); int i; + if (is_nd_volatile(&nd_region->dev)) + return -EINVAL; + /* no nvdimm or pmem api == flushing capability unknown */ if (nd_region->ndr_mappings == 0 || !IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API))