Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1206985 > unrolled thread
| Started by | Ross Zwisler <ross.zwisler@linux.intel.com> |
|---|---|
| First post | 2015-08-13 19:00 +0200 |
| Last post | 2015-08-13 19:00 +0200 |
| Articles | 2 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH v2 0/7] dax: I/O path enhancements Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-08-13 19:00 +0200
[PATCH v2 5/7] pmem: add wb_cache_pmem() and clear_pmem() Ross Zwisler <ross.zwisler@linux.intel.com> - 2015-08-13 19:00 +0200
| From | Ross Zwisler <ross.zwisler@linux.intel.com> |
|---|---|
| Date | 2015-08-13 19:00 +0200 |
| Subject | [PATCH v2 0/7] dax: I/O path enhancements |
| Message-ID | <pX41c-Hx-11@gated-at.bofh.it> |
The goal of this series is to enhance the DAX I/O path so that all operations that store data (I/O writes, zeroing blocks, punching holes, etc.) properly synchronize the stores to media using the PMEM API. This ensures that the data DAX is writing is durable on media before the operation completes. Patches 1-4 are a few random cleanups. Changes from v1: - Removed patches to PMEM for the "read flush" _DSM flag. These are different enough that they deserve their own series, and they have a separate baseline which is currently moving (Dan's memremap() series). - Added clear_pmem() PMEM API to zero DAX memory and flush it in one call. (Dave) - Open coded flushing in arch_wb_cache_pmem() instead of adding a generic clwb_flush_range(). This allowed me to avoid having extra memory barriers and instead rely completely on arch_wmb_pmem() for ordering. (Dave) - Moved the arch implementation of the PMEM API into it's own arch header (Christoph). Ross Zwisler (7): brd: make rd_size static pmem, x86: move x86 PMEM API to new pmem.h header pmem: remove layer when calling arch_has_wmb_pmem() pmem, x86: clean up conditional pmem includes pmem: add wb_cache_pmem() and clear_pmem() dax: update I/O path to do proper PMEM flushing pmem, dax: have direct_access use __pmem annotation Documentation/filesystems/Locking | 3 +- MAINTAINERS | 1 + arch/powerpc/sysdev/axonram.c | 7 ++- arch/x86/include/asm/cacheflush.h | 71 ---------------------- arch/x86/include/asm/pmem.h | 123 ++++++++++++++++++++++++++++++++++++++ drivers/block/brd.c | 6 +- drivers/nvdimm/pmem.c | 4 +- drivers/s390/block/dcssblk.c | 10 ++-- fs/block_dev.c | 2 +- fs/dax.c | 73 ++++++++++++++-------- include/linux/blkdev.h | 8 +-- include/linux/pmem.h | 66 ++++++++++++++++---- 12 files changed, 247 insertions(+), 127 deletions(-) create mode 100644 arch/x86/include/asm/pmem.h -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Ross Zwisler <ross.zwisler@linux.intel.com> |
|---|---|
| Date | 2015-08-13 19:00 +0200 |
| Subject | [PATCH v2 5/7] pmem: add wb_cache_pmem() and clear_pmem() |
| Message-ID | <pX41d-Hx-49@gated-at.bofh.it> |
| In reply to | #1206985 |
Add support for two new PMEM APIs, wb_cache_pmem() and clear_pmem().
The first, wb_cache_pmem(), is used to write back ranges of dirtied
cache lines to media in order to make stores durable. The contents of
the now-clean cache lines can potentially still reside in the cache
after this write back operation allowing subsequent loads to be serviced
from the cache.
The second, clear_pmem(), zeros a PMEM memory range and ensures that the
newly zeroed data is properly flushed from the processor cache to media.
This can be done either with normal writes followed by wb_cache_pmem()
calls, or by using non-temporal stores.
Both of these new APIs must be explicitly ordered using a wmb_pmem()
function call. Because both APIs are unordered they can be called as
needed without introducing any unwanted memory barriers.
Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
---
arch/x86/include/asm/pmem.h | 40 ++++++++++++++++++++++++++++++++++
include/linux/pmem.h | 53 ++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 90 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h
index 7f3413f..89b04c0 100644
--- a/arch/x86/include/asm/pmem.h
+++ b/arch/x86/include/asm/pmem.h
@@ -66,6 +66,46 @@ static inline void arch_wmb_pmem(void)
pcommit_sfence();
}
+/**
+ * arch_wb_cache_pmem - write back a cache range with CLWB
+ * @addr: virtual start address
+ * @size: number of bytes to write back
+ *
+ * Write back a cache range using the CLWB (cache line write back)
+ * instruction. This function requires explicit ordering with an
+ * arch_wmb_pmem() function call.
+ */
+static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size)
+{
+ u16 x86_clflush_size = boot_cpu_data.x86_clflush_size;
+ unsigned long clflush_mask = x86_clflush_size - 1;
+ void *vend = (void __force *)addr + size;
+ void *p;
+
+ for (p = (void *)((unsigned long)addr & ~clflush_mask);
+ p < vend; p += x86_clflush_size)
+ clwb(p);
+}
+
+/**
+ * arch_clear_pmem - zero a PMEM memory range
+ * @addr: virtual start address
+ * @size: number of bytes to zero
+ *
+ * Write zeros into the memory range starting at 'addr' for 'size' bytes.
+ * This function requires explicit ordering with an arch_wmb_pmem() call.
+ */
+static inline void arch_clear_pmem(void __pmem *addr, size_t size)
+{
+ /* TODO: implement the zeroing via non-temporal writes */
+ if (size == PAGE_SIZE && ((unsigned long)addr & ~PAGE_MASK) == 0)
+ clear_page((void __force *)addr);
+ else
+ memset((void __force *)addr, 0, size);
+
+ arch_wb_cache_pmem(addr, size);
+}
+
static inline bool arch_has_wmb_pmem(void)
{
#ifdef CONFIG_X86_64
diff --git a/include/linux/pmem.h b/include/linux/pmem.h
index 9d619d2..dd1b72c 100644
--- a/include/linux/pmem.h
+++ b/include/linux/pmem.h
@@ -39,12 +39,22 @@ static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src,
{
BUG();
}
+
+static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size)
+{
+ BUG();
+}
+
+static inline void arch_clear_pmem(void __pmem *addr, size_t size)
+{
+ BUG();
+}
#endif
/*
- * Architectures that define ARCH_HAS_PMEM_API must provide
- * implementations for arch_memremap_pmem(), arch_memcpy_to_pmem(),
- * arch_wmb_pmem(), and arch_has_wmb_pmem().
+ * Architectures that define ARCH_HAS_PMEM_API must provide implementations
+ * for arch_memremap_pmem(), arch_memcpy_to_pmem(), arch_wmb_pmem(),
+ * arch_wb_cache_pmem(), arch_clear_pmem() and arch_has_wmb_pmem().
*/
static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size)
@@ -90,6 +100,14 @@ static void __pmem *default_memremap_pmem(resource_size_t offset,
return (void __pmem __force *)ioremap_wt(offset, size);
}
+static inline void default_clear_pmem(void __pmem *addr, size_t size)
+{
+ if (size == PAGE_SIZE && ((unsigned long)addr & ~PAGE_MASK) == 0)
+ clear_page((void __force *)addr);
+ else
+ memset((void __force *)addr, 0, size);
+}
+
/**
* memremap_pmem - map physical persistent memory for pmem api
* @offset: physical address of persistent memory
@@ -142,4 +160,33 @@ static inline void wmb_pmem(void)
if (arch_has_pmem_api())
arch_wmb_pmem();
}
+
+/**
+ * wb_cache_pmem - write back a cache range
+ * @addr: virtual start address
+ * @size: number of bytes to write back
+ *
+ * This function requires explicit ordering with a wmb_pmem() call.
+ */
+static inline void wb_cache_pmem(void __pmem *addr, size_t size)
+{
+ if (arch_has_pmem_api())
+ arch_wb_cache_pmem(addr, size);
+}
+
+/**
+ * clear_pmem - zero a PMEM memory range
+ * @addr: virtual start address
+ * @size: number of bytes to zero
+ *
+ * Write zeros into the memory range starting at 'addr' for 'size' bytes.
+ * This function requires explicit ordering with a wmb_pmem() call.
+ */
+static inline void clear_pmem(void __pmem *addr, size_t size)
+{
+ if (arch_has_pmem_api())
+ arch_clear_pmem(addr, size);
+ else
+ default_clear_pmem(addr, size);
+}
#endif /* __PMEM_H__ */
--
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web