From: Joao Martins <joao.m.martins@oracle.com> To: Dan Williams <dan.j.williams@intel.com> Cc: linux-nvdimm@lists.01.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH v1 2/4] device-dax: Add an 'align' attribute Date: Thu, 16 Jul 2020 18:29:11 +0100 [thread overview] Message-ID: <20200716172913.19658-3-joao.m.martins@oracle.com> (raw) In-Reply-To: <20200716172913.19658-1-joao.m.martins@oracle.com> Introduce a device align attribute. While doing so, rename the region align attribute to be more explicitly named as so, but keep it named as @align to retain the API for tools like daxctl. Changes on align may not always be valid, when say certain mappings were created with 2M and then we switch to 1G. So, we validate all ranges against the new value being attempted, post resizing. Signed-off-by: Joao Martins <joao.m.martins@oracle.com> --- drivers/dax/bus.c | 101 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index 2578651c596e..eb384dd6a376 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -230,14 +230,15 @@ static ssize_t region_size_show(struct device *dev, static struct device_attribute dev_attr_region_size = __ATTR(size, 0444, region_size_show, NULL); -static ssize_t align_show(struct device *dev, +static ssize_t region_align_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dax_region *dax_region = dev_get_drvdata(dev); return sprintf(buf, "%u\n", dax_region->align); } -static DEVICE_ATTR_RO(align); +static struct device_attribute dev_attr_region_align = + __ATTR(align, 0400, region_align_show, NULL); #define for_each_dax_region_resource(dax_region, res) \ for (res = (dax_region)->res.child; res; res = res->sibling) @@ -488,7 +489,7 @@ static umode_t dax_region_visible(struct kobject *kobj, struct attribute *a, static struct attribute *dax_region_attributes[] = { &dev_attr_available_size.attr, &dev_attr_region_size.attr, - &dev_attr_align.attr, + &dev_attr_region_align.attr, &dev_attr_create.attr, &dev_attr_seed.attr, &dev_attr_delete.attr, @@ -855,14 +856,13 @@ static ssize_t size_show(struct device *dev, return sprintf(buf, "%llu\n", size); } -static bool alloc_is_aligned(struct dax_region *dax_region, - resource_size_t size) +static bool alloc_is_aligned(resource_size_t size, unsigned long align) { /* * The minimum mapping granularity for a device instance is a * single subsection, unless the arch says otherwise. */ - return IS_ALIGNED(size, max_t(unsigned long, dax_region->align, + return IS_ALIGNED(size, max_t(unsigned long, align, memremap_compat_align())); } @@ -958,7 +958,7 @@ static ssize_t dev_dax_resize(struct dax_region *dax_region, return dev_dax_shrink(dev_dax, size); to_alloc = size - dev_size; - if (dev_WARN_ONCE(dev, !alloc_is_aligned(dax_region, to_alloc), + if (dev_WARN_ONCE(dev, !alloc_is_aligned(to_alloc, dev_dax->align), "resize of %pa misaligned\n", &to_alloc)) return -ENXIO; @@ -1022,7 +1022,7 @@ static ssize_t size_store(struct device *dev, struct device_attribute *attr, if (rc) return rc; - if (!alloc_is_aligned(dax_region, val)) { + if (!alloc_is_aligned(val, dev_dax->align)) { dev_dbg(dev, "%s: size: %lld misaligned\n", __func__, val); return -EINVAL; } @@ -1041,6 +1041,87 @@ static ssize_t size_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(size); +static ssize_t align_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dev_dax *dev_dax = to_dev_dax(dev); + + return sprintf(buf, "%d\n", dev_dax->align); +} + +static ssize_t dev_dax_set_align(struct dev_dax *dev_dax, + unsigned long long align) +{ + resource_size_t dev_size = dev_dax_size(dev_dax); + struct device *dev = &dev_dax->dev; + ssize_t rc, i; + + if (dev->driver) + return -EBUSY; + + rc = -EINVAL; + if (dev_size > 0 && !alloc_is_aligned(dev_size, align)) { + dev_dbg(dev, "%s: align %llx invalid for size %llu\n", + __func__, align, dev_size); + return rc; + } + + for (i = 0; i < dev_dax->nr_range; i++) { + size_t len = range_len(&dev_dax->ranges[i].range); + + if (!alloc_is_aligned(len, align)) { + dev_dbg(dev, "%s: align %llx invalid for range %ld\n", + __func__, align, i); + return rc; + } + } + + switch (align) { + case PUD_SIZE: + if (!IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)) + break; + fallthrough; + case PMD_SIZE: + if (!has_transparent_hugepage()) + break; + fallthrough; + case PAGE_SIZE: + rc = 0; + break; + } + + if (!rc) + dev_dax->align = align; + + return rc; +} + +static ssize_t align_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct dev_dax *dev_dax = to_dev_dax(dev); + struct dax_region *dax_region = dev_dax->region; + unsigned long long val; + ssize_t rc; + + rc = kstrtoull(buf, 0, &val); + if (rc) + return -ENXIO; + + device_lock(dax_region->dev); + if (!dax_region->dev->driver) { + device_unlock(dax_region->dev); + return -ENXIO; + } + + device_lock(dev); + rc = dev_dax_set_align(dev_dax, val); + device_unlock(dev); + device_unlock(dax_region->dev); + return rc == 0 ? len : rc; +} +static DEVICE_ATTR_RW(align); + static int dev_dax_target_node(struct dev_dax *dev_dax) { struct dax_region *dax_region = dev_dax->region; @@ -1101,7 +1182,8 @@ static umode_t dev_dax_visible(struct kobject *kobj, struct attribute *a, int n) return 0; if (a == &dev_attr_numa_node.attr && !IS_ENABLED(CONFIG_NUMA)) return 0; - if (a == &dev_attr_size.attr && is_static(dax_region)) + if ((a == &dev_attr_align.attr || + a == &dev_attr_size.attr) && is_static(dax_region)) return 0444; return a->mode; } @@ -1110,6 +1192,7 @@ static struct attribute *dev_dax_attributes[] = { &dev_attr_modalias.attr, &dev_attr_size.attr, &dev_attr_target_node.attr, + &dev_attr_align.attr, &dev_attr_resource.attr, &dev_attr_numa_node.attr, NULL, -- 2.17.1 _______________________________________________ Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org To unsubscribe send an email to linux-nvdimm-leave@lists.01.org
WARNING: multiple messages have this Message-ID (diff)
From: Joao Martins <joao.m.martins@oracle.com> To: Dan Williams <dan.j.williams@intel.com> Cc: linux-nvdimm@lists.01.org, Vishal Verma <vishal.l.verma@intel.com>, Dave Jiang <dave.jiang@intel.com>, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH v1 2/4] device-dax: Add an 'align' attribute Date: Thu, 16 Jul 2020 18:29:11 +0100 [thread overview] Message-ID: <20200716172913.19658-3-joao.m.martins@oracle.com> (raw) In-Reply-To: <20200716172913.19658-1-joao.m.martins@oracle.com> Introduce a device align attribute. While doing so, rename the region align attribute to be more explicitly named as so, but keep it named as @align to retain the API for tools like daxctl. Changes on align may not always be valid, when say certain mappings were created with 2M and then we switch to 1G. So, we validate all ranges against the new value being attempted, post resizing. Signed-off-by: Joao Martins <joao.m.martins@oracle.com> --- drivers/dax/bus.c | 101 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 9 deletions(-) diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index 2578651c596e..eb384dd6a376 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -230,14 +230,15 @@ static ssize_t region_size_show(struct device *dev, static struct device_attribute dev_attr_region_size = __ATTR(size, 0444, region_size_show, NULL); -static ssize_t align_show(struct device *dev, +static ssize_t region_align_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dax_region *dax_region = dev_get_drvdata(dev); return sprintf(buf, "%u\n", dax_region->align); } -static DEVICE_ATTR_RO(align); +static struct device_attribute dev_attr_region_align = + __ATTR(align, 0400, region_align_show, NULL); #define for_each_dax_region_resource(dax_region, res) \ for (res = (dax_region)->res.child; res; res = res->sibling) @@ -488,7 +489,7 @@ static umode_t dax_region_visible(struct kobject *kobj, struct attribute *a, static struct attribute *dax_region_attributes[] = { &dev_attr_available_size.attr, &dev_attr_region_size.attr, - &dev_attr_align.attr, + &dev_attr_region_align.attr, &dev_attr_create.attr, &dev_attr_seed.attr, &dev_attr_delete.attr, @@ -855,14 +856,13 @@ static ssize_t size_show(struct device *dev, return sprintf(buf, "%llu\n", size); } -static bool alloc_is_aligned(struct dax_region *dax_region, - resource_size_t size) +static bool alloc_is_aligned(resource_size_t size, unsigned long align) { /* * The minimum mapping granularity for a device instance is a * single subsection, unless the arch says otherwise. */ - return IS_ALIGNED(size, max_t(unsigned long, dax_region->align, + return IS_ALIGNED(size, max_t(unsigned long, align, memremap_compat_align())); } @@ -958,7 +958,7 @@ static ssize_t dev_dax_resize(struct dax_region *dax_region, return dev_dax_shrink(dev_dax, size); to_alloc = size - dev_size; - if (dev_WARN_ONCE(dev, !alloc_is_aligned(dax_region, to_alloc), + if (dev_WARN_ONCE(dev, !alloc_is_aligned(to_alloc, dev_dax->align), "resize of %pa misaligned\n", &to_alloc)) return -ENXIO; @@ -1022,7 +1022,7 @@ static ssize_t size_store(struct device *dev, struct device_attribute *attr, if (rc) return rc; - if (!alloc_is_aligned(dax_region, val)) { + if (!alloc_is_aligned(val, dev_dax->align)) { dev_dbg(dev, "%s: size: %lld misaligned\n", __func__, val); return -EINVAL; } @@ -1041,6 +1041,87 @@ static ssize_t size_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(size); +static ssize_t align_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dev_dax *dev_dax = to_dev_dax(dev); + + return sprintf(buf, "%d\n", dev_dax->align); +} + +static ssize_t dev_dax_set_align(struct dev_dax *dev_dax, + unsigned long long align) +{ + resource_size_t dev_size = dev_dax_size(dev_dax); + struct device *dev = &dev_dax->dev; + ssize_t rc, i; + + if (dev->driver) + return -EBUSY; + + rc = -EINVAL; + if (dev_size > 0 && !alloc_is_aligned(dev_size, align)) { + dev_dbg(dev, "%s: align %llx invalid for size %llu\n", + __func__, align, dev_size); + return rc; + } + + for (i = 0; i < dev_dax->nr_range; i++) { + size_t len = range_len(&dev_dax->ranges[i].range); + + if (!alloc_is_aligned(len, align)) { + dev_dbg(dev, "%s: align %llx invalid for range %ld\n", + __func__, align, i); + return rc; + } + } + + switch (align) { + case PUD_SIZE: + if (!IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)) + break; + fallthrough; + case PMD_SIZE: + if (!has_transparent_hugepage()) + break; + fallthrough; + case PAGE_SIZE: + rc = 0; + break; + } + + if (!rc) + dev_dax->align = align; + + return rc; +} + +static ssize_t align_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct dev_dax *dev_dax = to_dev_dax(dev); + struct dax_region *dax_region = dev_dax->region; + unsigned long long val; + ssize_t rc; + + rc = kstrtoull(buf, 0, &val); + if (rc) + return -ENXIO; + + device_lock(dax_region->dev); + if (!dax_region->dev->driver) { + device_unlock(dax_region->dev); + return -ENXIO; + } + + device_lock(dev); + rc = dev_dax_set_align(dev_dax, val); + device_unlock(dev); + device_unlock(dax_region->dev); + return rc == 0 ? len : rc; +} +static DEVICE_ATTR_RW(align); + static int dev_dax_target_node(struct dev_dax *dev_dax) { struct dax_region *dax_region = dev_dax->region; @@ -1101,7 +1182,8 @@ static umode_t dev_dax_visible(struct kobject *kobj, struct attribute *a, int n) return 0; if (a == &dev_attr_numa_node.attr && !IS_ENABLED(CONFIG_NUMA)) return 0; - if (a == &dev_attr_size.attr && is_static(dax_region)) + if ((a == &dev_attr_align.attr || + a == &dev_attr_size.attr) && is_static(dax_region)) return 0444; return a->mode; } @@ -1110,6 +1192,7 @@ static struct attribute *dev_dax_attributes[] = { &dev_attr_modalias.attr, &dev_attr_size.attr, &dev_attr_target_node.attr, + &dev_attr_align.attr, &dev_attr_resource.attr, &dev_attr_numa_node.attr, NULL, -- 2.17.1
next prev parent reply other threads:[~2020-07-16 17:31 UTC|newest] Thread overview: 100+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-07-12 16:26 [PATCH v2 00/22] device-dax: Support sub-dividing soft-reserved ranges Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-12 16:26 ` [PATCH v2 01/22] x86/numa: Cleanup configuration dependent command-line options Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-12 16:26 ` [PATCH v2 02/22] x86/numa: Add 'nohmat' option Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-12 16:58 ` Randy Dunlap 2020-07-12 16:58 ` Randy Dunlap 2020-07-12 16:26 ` [PATCH v2 03/22] efi/fake_mem: Arrange for a resource entry per efi_fake_mem instance Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-12 16:26 ` [PATCH v2 04/22] ACPI: HMAT: Refactor hmat_register_target_device to hmem_register_device Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-12 16:26 ` [PATCH v2 05/22] resource: Report parent to walk_iomem_res_desc() callback Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-12 16:26 ` [PATCH v2 06/22] x86: Move NUMA_KEEP_MEMINFO and related definition to x86-internals Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-12 16:26 ` [PATCH v2 07/22] numa: Introduce a generic memory_add_physaddr_to_nid() Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-13 6:58 ` Mike Rapoport 2020-07-13 6:58 ` Mike Rapoport 2020-07-13 15:42 ` Dan Williams 2020-07-13 15:42 ` Dan Williams 2020-07-13 15:42 ` Dan Williams 2020-07-12 16:26 ` [PATCH v2 08/22] memblock: Introduce a generic phys_addr_to_target_node() Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-13 7:03 ` Mike Rapoport 2020-07-13 7:03 ` Mike Rapoport 2020-07-13 15:48 ` Dan Williams 2020-07-13 15:48 ` Dan Williams 2020-07-13 15:48 ` Dan Williams 2020-07-14 1:36 ` Justin He 2020-07-14 1:36 ` Justin He 2020-07-12 16:26 ` [PATCH v2 09/22] arm64: Convert to generic memblock for numa-info Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-12 16:26 ` [PATCH v2 10/22] ACPI: HMAT: Attach a device for each soft-reserved range Dan Williams 2020-07-12 16:26 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 11/22] device-dax: Drop the dax_region.pfn_flags attribute Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 12/22] device-dax: Move instance creation parameters to 'struct dev_dax_data' Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 13/22] device-dax: Make pgmap optional for instance creation Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 14/22] device-dax: Kill dax_kmem_res Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 15/22] device-dax: Add an allocation interface for device-dax instances Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 16/22] device-dax: Introduce 'seed' devices Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 17/22] drivers/base: Make device_find_child_by_name() compatible with sysfs inputs Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 17:09 ` Greg Kroah-Hartman 2020-07-12 17:09 ` Greg Kroah-Hartman 2020-07-13 15:39 ` Dan Williams 2020-07-13 15:39 ` Dan Williams 2020-07-13 15:39 ` Dan Williams 2020-07-13 15:52 ` Greg Kroah-Hartman 2020-07-13 15:52 ` Greg Kroah-Hartman 2020-07-13 16:09 ` Dan Williams 2020-07-13 16:09 ` Dan Williams 2020-07-13 16:09 ` Dan Williams 2020-07-13 16:12 ` Greg Kroah-Hartman 2020-07-13 16:12 ` Greg Kroah-Hartman 2020-07-13 16:36 ` Dan Williams 2020-07-13 16:36 ` Dan Williams 2020-07-13 16:36 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 18/22] device-dax: Add resize support Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 19/22] mm/memremap_pages: Convert to 'struct range' Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-13 16:36 ` Ralph Campbell 2020-07-13 16:36 ` Ralph Campbell 2020-07-13 16:54 ` Dan Williams 2020-07-13 16:54 ` Dan Williams 2020-07-13 16:54 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 20/22] mm/memremap_pages: Support multiple ranges per invocation Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 16:27 ` [PATCH v2 21/22] device-dax: Add dis-contiguous resource support Dan Williams 2020-07-12 16:27 ` Dan Williams 2020-07-12 16:28 ` [PATCH v2 22/22] device-dax: Introduce 'mapping' devices Dan Williams 2020-07-12 16:28 ` Dan Williams 2020-07-16 13:18 ` Joao Martins 2020-07-16 13:18 ` Joao Martins 2020-07-16 16:00 ` Dan Williams 2020-07-16 16:00 ` Dan Williams 2020-07-16 16:00 ` Dan Williams 2020-07-16 19:04 ` Joao Martins 2020-07-16 19:04 ` Joao Martins 2020-07-16 17:29 ` [PATCH v1 0/4] device-dax: Further improvements to subdivision Joao Martins 2020-07-16 17:29 ` Joao Martins 2020-07-16 17:29 ` [PATCH v1 1/4] device-dax: Make align a per-device property Joao Martins 2020-07-16 17:29 ` Joao Martins 2020-07-16 17:29 ` Joao Martins [this message] 2020-07-16 17:29 ` [PATCH v1 2/4] device-dax: Add an 'align' attribute Joao Martins 2020-07-31 14:52 ` Dan Williams 2020-07-31 14:52 ` Dan Williams 2020-07-31 14:52 ` Dan Williams 2020-07-16 17:29 ` [PATCH v1 3/4] dax/hmem: Introduce dax_hmem.region_idle parameter Joao Martins 2020-07-16 17:29 ` Joao Martins 2020-07-16 17:29 ` [PATCH v1 4/4] device-dax: Add a range mapping allocation attribute Joao Martins 2020-07-16 17:29 ` Joao Martins
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200716172913.19658-3-joao.m.martins@oracle.com \ --to=joao.m.martins@oracle.com \ --cc=dan.j.williams@intel.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=linux-nvdimm@lists.01.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.