From: Dan Williams Date: Fri, 5 May 2017 06:38:43 +0000 (-0700) Subject: Merge branch 'for-4.12/dax' into libnvdimm-for-next X-Git-Tag: v4.12-rc1~83^2 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=736163671bcb163fc82600b46c83dfa89d532d95;p=users%2Fjedix%2Flinux-maple.git Merge branch 'for-4.12/dax' into libnvdimm-for-next --- 736163671bcb163fc82600b46c83dfa89d532d95 diff --cc drivers/dax/dax-private.h index b1cd7a8e5ab9,000000000000..b6fc4f04636d mode 100644,000000..100644 --- a/drivers/dax/dax-private.h +++ b/drivers/dax/dax-private.h @@@ -1,61 -1,0 +1,57 @@@ +/* + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#ifndef __DAX_PRIVATE_H__ +#define __DAX_PRIVATE_H__ + +#include +#include + +/** + * struct dax_region - mapping infrastructure for dax devices + * @id: kernel-wide unique region for a memory range + * @base: linear address corresponding to @res + * @kref: to pin while other agents have a need to do lookups + * @dev: parent device backing this region + * @align: allocation and mapping alignment for child dax devices + * @res: physical address range of the region + * @pfn_flags: identify whether the pfns are paged back or not + */ +struct dax_region { + int id; + struct ida ida; + void *base; + struct kref kref; + struct device *dev; + unsigned int align; + struct resource res; + unsigned long pfn_flags; +}; + +/** - * struct dax_dev - subdivision of a dax region ++ * struct dev_dax - instance data for a subdivision of a dax region + * @region - parent region - * @inode - inode - * @dev - device backing the character device - * @cdev - core chardev data - * @alive - !alive + srcu grace period == no new mappings can be established ++ * @dax_dev - core dax functionality ++ * @dev - device core + * @id - child id in the region + * @num_resources - number of physical address extents in this device + * @res - array of physical address ranges + */ - struct dax_dev { ++struct dev_dax { + struct dax_region *region; - struct inode *inode; ++ struct dax_device *dax_dev; + struct device dev; - struct cdev cdev; - bool alive; + int id; + int num_resources; + struct resource res[0]; +}; +#endif diff --cc drivers/dax/device.c index 5e8302d3a89c,a0db055054a4..006e657dfcb9 --- a/drivers/dax/device.c +++ b/drivers/dax/device.c @@@ -22,25 -19,49 +19,16 @@@ #include #include #include +#include "dax-private.h" #include "dax.h" - static dev_t dax_devt; - DEFINE_STATIC_SRCU(dax_srcu); static struct class *dax_class; - static DEFINE_IDA(dax_minor_ida); - static int nr_dax = CONFIG_NR_DEV_DAX; - module_param(nr_dax, int, S_IRUGO); - static struct vfsmount *dax_mnt; - static struct kmem_cache *dax_cache __read_mostly; - static struct super_block *dax_superblock __read_mostly; - MODULE_PARM_DESC(nr_dax, "max number of device-dax instances"); -/** - * struct dax_region - mapping infrastructure for dax devices - * @id: kernel-wide unique region for a memory range - * @base: linear address corresponding to @res - * @kref: to pin while other agents have a need to do lookups - * @dev: parent device backing this region - * @align: allocation and mapping alignment for child dax devices - * @res: physical address range of the region - * @pfn_flags: identify whether the pfns are paged back or not - */ -struct dax_region { - int id; - struct ida ida; - void *base; - struct kref kref; - struct device *dev; - unsigned int align; - struct resource res; - unsigned long pfn_flags; -}; - -/** - * struct dev_dax - instance data for a subdivision of a dax region - * @region - parent region - * @dax_dev - core dax functionality - * @dev - device core - * @id - child id in the region - * @num_resources - number of physical address extents in this device - * @res - array of physical address ranges +/* + * Rely on the fact that drvdata is set before the attributes are + * registered, and that the attributes are unregistered before drvdata + * is cleared to assume that drvdata is always valid. */ -struct dev_dax { - struct dax_region *region; - struct dax_device *dax_dev; - struct device dev; - int id; - int num_resources; - struct resource res[0]; -}; - static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf) { @@@ -340,8 -271,7 +217,8 @@@ static int check_vma(struct dev_dax *de return 0; } -static phys_addr_t pgoff_to_phys(struct dev_dax *dev_dax, pgoff_t pgoff, +/* see "strong" declaration in tools/testing/nvdimm/dax-dev.c */ - __weak phys_addr_t dax_pgoff_to_phys(struct dax_dev *dax_dev, pgoff_t pgoff, ++__weak phys_addr_t dax_pgoff_to_phys(struct dev_dax *dev_dax, pgoff_t pgoff, unsigned long size) { struct resource *res; @@@ -386,7 -317,7 +264,7 @@@ static int __dev_dax_pte_fault(struct d if (fault_size != dax_region->align) return VM_FAULT_SIGBUS; - phys = dax_pgoff_to_phys(dax_dev, vmf->pgoff, PAGE_SIZE); - phys = pgoff_to_phys(dev_dax, vmf->pgoff, PAGE_SIZE); ++ phys = dax_pgoff_to_phys(dev_dax, vmf->pgoff, PAGE_SIZE); if (phys == -1) { dev_dbg(dev, "%s: pgoff_to_phys(%#lx) failed\n", __func__, vmf->pgoff); @@@ -441,7 -373,7 +320,7 @@@ static int __dev_dax_pmd_fault(struct d return VM_FAULT_SIGBUS; pgoff = linear_page_index(vmf->vma, pmd_addr); - phys = dax_pgoff_to_phys(dax_dev, pgoff, PMD_SIZE); - phys = pgoff_to_phys(dev_dax, pgoff, PMD_SIZE); ++ phys = dax_pgoff_to_phys(dev_dax, pgoff, PMD_SIZE); if (phys == -1) { dev_dbg(dev, "%s: pgoff_to_phys(%#lx) failed\n", __func__, pgoff); @@@ -492,7 -425,7 +372,7 @@@ static int __dev_dax_pud_fault(struct d return VM_FAULT_SIGBUS; pgoff = linear_page_index(vmf->vma, pud_addr); - phys = dax_pgoff_to_phys(dax_dev, pgoff, PUD_SIZE); - phys = pgoff_to_phys(dev_dax, pgoff, PUD_SIZE); ++ phys = dax_pgoff_to_phys(dev_dax, pgoff, PUD_SIZE); if (phys == -1) { dev_dbg(dev, "%s: pgoff_to_phys(%#lx) failed\n", __func__, pgoff); diff --cc tools/testing/nvdimm/Kbuild index 6dcb3c4d53be,2033ad03b8cd..d870520da68b --- a/tools/testing/nvdimm/Kbuild +++ b/tools/testing/nvdimm/Kbuild @@@ -48,10 -51,12 +51,13 @@@ nd_blk-y += config_check. nd_e820-y := $(NVDIMM_SRC)/e820.o nd_e820-y += config_check.o - dax-y := $(DAX_SRC)/dax.o - dax-y += dax-dev.o + dax-y := $(DAX_SRC)/super.o dax-y += config_check.o + device_dax-y := $(DAX_SRC)/device.o ++device_dax-y += dax-dev.o + device_dax-y += config_check.o + dax_pmem-y := $(DAX_SRC)/pmem.o dax_pmem-y += config_check.o diff --cc tools/testing/nvdimm/dax-dev.c index e89721d8924c,000000000000..36ee3d8797c3 mode 100644,000000..100644 --- a/tools/testing/nvdimm/dax-dev.c +++ b/tools/testing/nvdimm/dax-dev.c @@@ -1,49 -1,0 +1,49 @@@ +/* + * Copyright (c) 2016, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#include "test/nfit_test.h" +#include +#include "../../../drivers/dax/dax-private.h" + - phys_addr_t dax_pgoff_to_phys(struct dax_dev *dax_dev, pgoff_t pgoff, ++phys_addr_t dax_pgoff_to_phys(struct dev_dax *dev_dax, pgoff_t pgoff, + unsigned long size) +{ + struct resource *res; + phys_addr_t addr; + int i; + - for (i = 0; i < dax_dev->num_resources; i++) { - res = &dax_dev->res[i]; ++ for (i = 0; i < dev_dax->num_resources; i++) { ++ res = &dev_dax->res[i]; + addr = pgoff * PAGE_SIZE + res->start; + if (addr >= res->start && addr <= res->end) + break; + pgoff -= PHYS_PFN(resource_size(res)); + } + - if (i < dax_dev->num_resources) { - res = &dax_dev->res[i]; ++ if (i < dev_dax->num_resources) { ++ res = &dev_dax->res[i]; + if (addr + size - 1 <= res->end) { + if (get_nfit_res(addr)) { + struct page *page; + - if (dax_dev->region->align > PAGE_SIZE) ++ if (dev_dax->region->align > PAGE_SIZE) + return -1; + + page = vmalloc_to_page((void *)addr); + return PFN_PHYS(page_to_pfn(page)); + } else + return addr; + } + } + + return -1; +}