Message ID | 1450502540-8744-2-git-send-email-ross.zwisler@linux.intel.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
On Fri, 18 Dec 2015 22:22:14 -0700 Ross Zwisler <ross.zwisler@linux.intel.com> wrote: > The function __arch_wb_cache_pmem() was already an internal implementation > detail of the x86 PMEM API, but this functionality needs to be exported as > part of the general PMEM API to handle the fsync/msync case for DAX mmaps. > > One thing worth noting is that we really do want this to be part of the > PMEM API as opposed to a stand-alone function like clflush_cache_range() > because of ordering restrictions. By having wb_cache_pmem() as part of the > PMEM API we can leave it unordered, call it multiple times to write back > large amounts of memory, and then order the multiple calls with a single > wmb_pmem(). > > @@ -138,7 +139,7 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size) > else > memset(vaddr, 0, size); > > - __arch_wb_cache_pmem(vaddr, size); > + arch_wb_cache_pmem(addr, size); > } > reject. I made this arch_wb_cache_pmem(vaddr, size); due to Dan's http://www.ozlabs.org/~akpm/mmots/broken-out/pmem-dax-clean-up-clear_pmem.patch
On Tue, Dec 22, 2015 at 02:44:40PM -0800, Andrew Morton wrote: > On Fri, 18 Dec 2015 22:22:14 -0700 Ross Zwisler <ross.zwisler@linux.intel.com> wrote: > > > The function __arch_wb_cache_pmem() was already an internal implementation > > detail of the x86 PMEM API, but this functionality needs to be exported as > > part of the general PMEM API to handle the fsync/msync case for DAX mmaps. > > > > One thing worth noting is that we really do want this to be part of the > > PMEM API as opposed to a stand-alone function like clflush_cache_range() > > because of ordering restrictions. By having wb_cache_pmem() as part of the > > PMEM API we can leave it unordered, call it multiple times to write back > > large amounts of memory, and then order the multiple calls with a single > > wmb_pmem(). > > > > @@ -138,7 +139,7 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size) > > else > > memset(vaddr, 0, size); > > > > - __arch_wb_cache_pmem(vaddr, size); > > + arch_wb_cache_pmem(addr, size); > > } > > > > reject. I made this > > arch_wb_cache_pmem(vaddr, size); > > due to Dan's > http://www.ozlabs.org/~akpm/mmots/broken-out/pmem-dax-clean-up-clear_pmem.patch The first argument seems wrong to me - in arch_clear_pmem() 'addr' and 'vaddr' are the same address, with the only difference being 'addr' has the __pmem annotation. As of this patch arch_wb_cache_pmem() follows the lead of the rest of the exported PMEM API functions and takes an argument that has the __pmem annotation, so I believe it should be: arch_wb_cache_pmem(addr, size); Without this I think you'll get a sparse warning. This will be fixed up in the next version of my series which build upon Dan's patches.
diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h index d8ce3ec..6c7ade0 100644 --- a/arch/x86/include/asm/pmem.h +++ b/arch/x86/include/asm/pmem.h @@ -67,18 +67,19 @@ static inline void arch_wmb_pmem(void) } /** - * __arch_wb_cache_pmem - write back a cache range with CLWB + * arch_wb_cache_pmem - write back a cache range with CLWB * @vaddr: 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() call. This API is internal to the x86 PMEM implementation. + * arch_wmb_pmem() call. */ -static inline void __arch_wb_cache_pmem(void *vaddr, size_t size) +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 *vaddr = (void __force *)addr; void *vend = vaddr + size; void *p; @@ -115,7 +116,7 @@ static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes, len = copy_from_iter_nocache(vaddr, bytes, i); if (__iter_needs_pmem_wb(i)) - __arch_wb_cache_pmem(vaddr, bytes); + arch_wb_cache_pmem(addr, bytes); return len; } @@ -138,7 +139,7 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size) else memset(vaddr, 0, size); - __arch_wb_cache_pmem(vaddr, size); + arch_wb_cache_pmem(addr, size); } static inline bool __arch_has_wmb_pmem(void) diff --git a/include/linux/pmem.h b/include/linux/pmem.h index acfea8c..7c3d11a 100644 --- a/include/linux/pmem.h +++ b/include/linux/pmem.h @@ -53,12 +53,18 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size) { BUG(); } + +static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size) +{ + BUG(); +} #endif /* * Architectures that define ARCH_HAS_PMEM_API must provide * implementations for arch_memcpy_to_pmem(), arch_wmb_pmem(), - * arch_copy_from_iter_pmem(), arch_clear_pmem() and arch_has_wmb_pmem(). + * arch_copy_from_iter_pmem(), arch_clear_pmem(), arch_wb_cache_pmem() + * and arch_has_wmb_pmem(). */ static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size) { @@ -178,4 +184,18 @@ static inline void clear_pmem(void __pmem *addr, size_t size) else default_clear_pmem(addr, size); } + +/** + * wb_cache_pmem - write back processor cache for PMEM memory range + * @addr: virtual start address + * @size: number of bytes to write back + * + * Write back the processor cache range starting at 'addr' for 'size' bytes. + * 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); +} #endif /* __PMEM_H__ */
The function __arch_wb_cache_pmem() was already an internal implementation detail of the x86 PMEM API, but this functionality needs to be exported as part of the general PMEM API to handle the fsync/msync case for DAX mmaps. One thing worth noting is that we really do want this to be part of the PMEM API as opposed to a stand-alone function like clflush_cache_range() because of ordering restrictions. By having wb_cache_pmem() as part of the PMEM API we can leave it unordered, call it multiple times to write back large amounts of memory, and then order the multiple calls with a single wmb_pmem(). Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com> --- arch/x86/include/asm/pmem.h | 11 ++++++----- include/linux/pmem.h | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 6 deletions(-)