Messages in this thread Patch in this message | | | From | Matthew Wilcox <> | Subject | [PATCH 4/5] Add memfill() | Date | Wed, 8 Mar 2017 12:24:05 -0800 |
| |
From: Matthew Wilcox <mawilcox@microsoft.com>
Similar to Lars Wirzenius' memfill(), this version has optimisations for source sizes of 1, 2, 4 (and 8 on 64 bit architectures).
Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com> --- include/linux/string.h | 3 +++ lib/string.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+)
diff --git a/include/linux/string.h b/include/linux/string.h index 642a82290a25..f340e6fb309f 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -112,6 +112,9 @@ static inline void *memset_l(unsigned long *p, unsigned long v, #endif } #endif +#ifndef __HAVE_ARCH_MEMFILL +extern void memfill(void *, __kernel_size_t, void *, __kernel_size_t); +#endif #ifndef __HAVE_ARCH_MEMCPY extern void * memcpy(void *,const void *,__kernel_size_t); #endif diff --git a/lib/string.c b/lib/string.c index 85628c8d3abd..d22711e6490a 100644 --- a/lib/string.c +++ b/lib/string.c @@ -741,6 +741,47 @@ EXPORT_SYMBOL(memset64); #endif #endif +#ifndef __HAVE_ARCH_MEMFILL +/** + * memfill() - Fill a region of memory with copies of another region + * @dst: Destination address + * @dsz: Size of destination area + * @src: Source address + * @ssz: Size of source area + */ +void memfill(void *dst, size_t dsz, void *src, size_t ssz) +{ + if (ssz == 1) { + memset(dst, *(unsigned char *)src, dsz); + return; + } else if (ssz == sizeof(short)) { + uint32_t v = *(unsigned short *)src; + v |= (v << 16); + + memset32(dst, v, dsz / sizeof(uint32_t)); + dst = (uint32_t *)dst + dsz / sizeof(uint32_t); + dsz %= sizeof(uint32_t); + } else if (ssz == sizeof(int)) { + memset32(dst, *(uint32_t *)src, dsz / sizeof(uint32_t)); + dst = (uint32_t *)dst + dsz / sizeof(uint32_t); + dsz %= sizeof(int); + } else if (ssz == sizeof(long)) { + memset_l(dst, *(long *)src, dsz / sizeof(long)); + dst = (long *)dst + dsz / sizeof(long); + dsz %= sizeof(long); + } else { + while (dsz >= ssz) { + memcpy(dst, src, ssz); + dsz -= ssz; + dst += ssz; + } + } + if (dsz) + memcpy(dst, src, dsz); +} +EXPORT_SYMBOL(memfill); +#endif + #ifndef __HAVE_ARCH_MEMCPY /** * memcpy - Copy one area of memory to another -- 2.11.0
| |