From: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
To: linuxppc-dev@lists.ozlabs.org, mpe@ellerman.id.au,
linux-nvdimm@lists.01.org, dan.j.williams@intel.com
Cc: Jan Kara <jack@suse.cz>,
msuchanek@suse.de,
"Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
Subject: [RFC PATCH v2 1/5] libnvdimm/dax: Add a dax flag to control synchronous fault support
Date: Tue, 2 Jun 2020 13:19:05 +0530 [thread overview]
Message-ID: <20200602074909.36738-1-aneesh.kumar@linux.ibm.com> (raw)
With POWER10, architecture is adding new pmem flush and sync instructions.
The kernel should prevent the usage of MAP_SYNC if applications are not using
the new instructions on newer hardware
This patch adds a dax attribute (/sys/bus/nd/devices/region0/pfn0.1/block/pmem0/dax/sync_fault)
which can be used to control this flag. If the device supports synchronous flush
then userspace can update this attribute to enable/disable the synchronous
fault. The attribute is only visible if there is write cache enabled on the device.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
drivers/dax/super.c | 73 ++++++++++++++++++++++++++++++++++++++++++++-
mm/Kconfig | 3 ++
2 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 8e32345be0f7..980f7be7e56d 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -198,6 +198,12 @@ enum dax_device_flags {
DAXDEV_WRITE_CACHE,
/* flag to check if device supports synchronous flush */
DAXDEV_SYNC,
+ /*
+ * flag to indicate whether synchronous flush is enabled.
+ * Some platform may want to disable synchronous flush support
+ * even though device supports the same.
+ */
+ DAXDEV_SYNC_ENABLED,
};
/**
@@ -254,6 +260,60 @@ static ssize_t write_cache_store(struct device *dev,
}
static DEVICE_ATTR_RW(write_cache);
+static bool dax_synchronous_enabled(struct dax_device *dax_dev)
+{
+ return test_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
+}
+
+static void set_dax_synchronous_enable(struct dax_device *dax_dev, bool enable)
+{
+ if (!test_bit(DAXDEV_SYNC, &dax_dev->flags))
+ return;
+
+ if (enable)
+ set_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
+ else
+ clear_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
+}
+
+
+static ssize_t sync_fault_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dax_device *dax_dev = dax_get_by_host(dev_name(dev));
+ ssize_t rc;
+
+ WARN_ON_ONCE(!dax_dev);
+ if (!dax_dev)
+ return -ENXIO;
+
+ rc = sprintf(buf, "%d\n", !!__dax_synchronous(dax_dev));
+ put_dax(dax_dev);
+ return rc;
+}
+
+static ssize_t sync_fault_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ bool enable_sync;
+ int rc = strtobool(buf, &enable_sync);
+ struct dax_device *dax_dev = dax_get_by_host(dev_name(dev));
+
+ WARN_ON_ONCE(!dax_dev);
+ if (!dax_dev)
+ return -ENXIO;
+
+ if (rc)
+ len = rc;
+ else
+ set_dax_synchronous_enable(dax_dev, enable_sync);
+
+ put_dax(dax_dev);
+ return len;
+}
+
+static DEVICE_ATTR_RW(sync_fault);
+
static umode_t dax_visible(struct kobject *kobj, struct attribute *a, int n)
{
struct device *dev = container_of(kobj, typeof(*dev), kobj);
@@ -267,11 +327,18 @@ static umode_t dax_visible(struct kobject *kobj, struct attribute *a, int n)
if (a == &dev_attr_write_cache.attr)
return 0;
#endif
+ if (a == &dev_attr_sync_fault.attr) {
+ if (dax_write_cache_enabled(dax_dev))
+ return a->mode;
+ return 0;
+ }
+
return a->mode;
}
static struct attribute *dax_attributes[] = {
&dev_attr_write_cache.attr,
+ &dev_attr_sync_fault.attr,
NULL,
};
@@ -394,13 +461,17 @@ EXPORT_SYMBOL_GPL(dax_write_cache_enabled);
bool __dax_synchronous(struct dax_device *dax_dev)
{
- return test_bit(DAXDEV_SYNC, &dax_dev->flags);
+ return test_bit(DAXDEV_SYNC, &dax_dev->flags) &&
+ test_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
}
EXPORT_SYMBOL_GPL(__dax_synchronous);
void __set_dax_synchronous(struct dax_device *dax_dev)
{
set_bit(DAXDEV_SYNC, &dax_dev->flags);
+#ifndef CONFIG_ARCH_MAP_SYNC_DISABLE
+ set_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
+#endif
}
EXPORT_SYMBOL_GPL(__set_dax_synchronous);
diff --git a/mm/Kconfig b/mm/Kconfig
index c1acc34c1c35..38fd7cfbfca8 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -867,4 +867,7 @@ config ARCH_HAS_HUGEPD
config MAPPING_DIRTY_HELPERS
bool
+config ARCH_MAP_SYNC_DISABLE
+ bool
+
endmenu
--
2.26.2
_______________________________________________
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: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
To: linuxppc-dev@lists.ozlabs.org, mpe@ellerman.id.au,
linux-nvdimm@lists.01.org, dan.j.williams@intel.com
Cc: Jan Kara <jack@suse.cz>, Jeff Moyer <jmoyer@redhat.com>,
msuchanek@suse.de, oohall@gmail.com,
"Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
Subject: [RFC PATCH v2 1/5] libnvdimm/dax: Add a dax flag to control synchronous fault support
Date: Tue, 2 Jun 2020 13:19:05 +0530 [thread overview]
Message-ID: <20200602074909.36738-1-aneesh.kumar@linux.ibm.com> (raw)
With POWER10, architecture is adding new pmem flush and sync instructions.
The kernel should prevent the usage of MAP_SYNC if applications are not using
the new instructions on newer hardware
This patch adds a dax attribute (/sys/bus/nd/devices/region0/pfn0.1/block/pmem0/dax/sync_fault)
which can be used to control this flag. If the device supports synchronous flush
then userspace can update this attribute to enable/disable the synchronous
fault. The attribute is only visible if there is write cache enabled on the device.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
drivers/dax/super.c | 73 ++++++++++++++++++++++++++++++++++++++++++++-
mm/Kconfig | 3 ++
2 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 8e32345be0f7..980f7be7e56d 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -198,6 +198,12 @@ enum dax_device_flags {
DAXDEV_WRITE_CACHE,
/* flag to check if device supports synchronous flush */
DAXDEV_SYNC,
+ /*
+ * flag to indicate whether synchronous flush is enabled.
+ * Some platform may want to disable synchronous flush support
+ * even though device supports the same.
+ */
+ DAXDEV_SYNC_ENABLED,
};
/**
@@ -254,6 +260,60 @@ static ssize_t write_cache_store(struct device *dev,
}
static DEVICE_ATTR_RW(write_cache);
+static bool dax_synchronous_enabled(struct dax_device *dax_dev)
+{
+ return test_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
+}
+
+static void set_dax_synchronous_enable(struct dax_device *dax_dev, bool enable)
+{
+ if (!test_bit(DAXDEV_SYNC, &dax_dev->flags))
+ return;
+
+ if (enable)
+ set_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
+ else
+ clear_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
+}
+
+
+static ssize_t sync_fault_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dax_device *dax_dev = dax_get_by_host(dev_name(dev));
+ ssize_t rc;
+
+ WARN_ON_ONCE(!dax_dev);
+ if (!dax_dev)
+ return -ENXIO;
+
+ rc = sprintf(buf, "%d\n", !!__dax_synchronous(dax_dev));
+ put_dax(dax_dev);
+ return rc;
+}
+
+static ssize_t sync_fault_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t len)
+{
+ bool enable_sync;
+ int rc = strtobool(buf, &enable_sync);
+ struct dax_device *dax_dev = dax_get_by_host(dev_name(dev));
+
+ WARN_ON_ONCE(!dax_dev);
+ if (!dax_dev)
+ return -ENXIO;
+
+ if (rc)
+ len = rc;
+ else
+ set_dax_synchronous_enable(dax_dev, enable_sync);
+
+ put_dax(dax_dev);
+ return len;
+}
+
+static DEVICE_ATTR_RW(sync_fault);
+
static umode_t dax_visible(struct kobject *kobj, struct attribute *a, int n)
{
struct device *dev = container_of(kobj, typeof(*dev), kobj);
@@ -267,11 +327,18 @@ static umode_t dax_visible(struct kobject *kobj, struct attribute *a, int n)
if (a == &dev_attr_write_cache.attr)
return 0;
#endif
+ if (a == &dev_attr_sync_fault.attr) {
+ if (dax_write_cache_enabled(dax_dev))
+ return a->mode;
+ return 0;
+ }
+
return a->mode;
}
static struct attribute *dax_attributes[] = {
&dev_attr_write_cache.attr,
+ &dev_attr_sync_fault.attr,
NULL,
};
@@ -394,13 +461,17 @@ EXPORT_SYMBOL_GPL(dax_write_cache_enabled);
bool __dax_synchronous(struct dax_device *dax_dev)
{
- return test_bit(DAXDEV_SYNC, &dax_dev->flags);
+ return test_bit(DAXDEV_SYNC, &dax_dev->flags) &&
+ test_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
}
EXPORT_SYMBOL_GPL(__dax_synchronous);
void __set_dax_synchronous(struct dax_device *dax_dev)
{
set_bit(DAXDEV_SYNC, &dax_dev->flags);
+#ifndef CONFIG_ARCH_MAP_SYNC_DISABLE
+ set_bit(DAXDEV_SYNC_ENABLED, &dax_dev->flags);
+#endif
}
EXPORT_SYMBOL_GPL(__set_dax_synchronous);
diff --git a/mm/Kconfig b/mm/Kconfig
index c1acc34c1c35..38fd7cfbfca8 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -867,4 +867,7 @@ config ARCH_HAS_HUGEPD
config MAPPING_DIRTY_HELPERS
bool
+config ARCH_MAP_SYNC_DISABLE
+ bool
+
endmenu
--
2.26.2
next reply other threads:[~2020-06-02 7:49 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-02 7:49 Aneesh Kumar K.V [this message]
2020-06-02 7:49 ` [RFC PATCH v2 1/5] libnvdimm/dax: Add a dax flag to control synchronous fault support Aneesh Kumar K.V
2020-06-02 7:49 ` [RFC PATCH v2 2/5] powerpc/pmem: Disable synchronous fault by default Aneesh Kumar K.V
2020-06-02 7:49 ` Aneesh Kumar K.V
2020-06-02 7:49 ` [RFC PATCH v2 3/5] libnvdimm/dax: Make DAXDEV_SYNC_ENABLED flag region-specific Aneesh Kumar K.V
2020-06-02 7:49 ` Aneesh Kumar K.V
2020-06-02 7:49 ` [RFC PATCH v2 4/5] powerpc/papr_scm: disable MAP_SYNC for newer hardware Aneesh Kumar K.V
2020-06-02 7:49 ` Aneesh Kumar K.V
2020-06-02 7:49 ` [RFC PATCH v2 5/5] libnvdimm: Add prctl control for disabling synchronous fault support Aneesh Kumar K.V
2020-06-02 7:49 ` Aneesh Kumar K.V
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=20200602074909.36738-1-aneesh.kumar@linux.ibm.com \
--to=aneesh.kumar@linux.ibm.com \
--cc=dan.j.williams@intel.com \
--cc=jack@suse.cz \
--cc=linux-nvdimm@lists.01.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mpe@ellerman.id.au \
--cc=msuchanek@suse.de \
/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: link
Be 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.