diff options
author | mav <mav@FreeBSD.org> | 2014-01-05 22:09:18 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2014-01-05 22:09:18 +0000 |
commit | fe82b61321d95949dd3b45f4e9ea7923b97ec6d8 (patch) | |
tree | 8618a1d268205f0114f8e8fbe9fac74ebfb08806 | |
parent | 1bba01828c15c706eae833685b7f0c07c42f7c54 (diff) | |
download | FreeBSD-src-fe82b61321d95949dd3b45f4e9ea7923b97ec6d8.zip FreeBSD-src-fe82b61321d95949dd3b45f4e9ea7923b97ec6d8.tar.gz |
MFC r258137:
Introduce allocation cache to store LZ4 compression contexts without kicking
VM subsystem twice for every written record.
Tests on 24-core system show double reduction of CPU time spent on copying
single large well-compressed file.
This patch is not really needed on illumos (while not harm either) since
their memory allocator by default uses caching for all requests up to 128K.
3 files changed, 28 insertions, 2 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lz4.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lz4.c index 0f55cc8..a7691d6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lz4.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/lz4.c @@ -44,6 +44,8 @@ static int LZ4_compressCtx(void *ctx, const char *source, char *dest, static int LZ4_compress64kCtx(void *ctx, const char *source, char *dest, int isize, int osize); +static kmem_cache_t *lz4_ctx_cache; + /*ARGSUSED*/ size_t lz4_compress(void *s_start, void *d_start, size_t s_len, size_t d_len, int n) @@ -840,7 +842,7 @@ static int real_LZ4_compress(const char *source, char *dest, int isize, int osize) { #if HEAPMODE - void *ctx = kmem_zalloc(sizeof (struct refTables), KM_NOSLEEP); + void *ctx = kmem_cache_alloc(lz4_ctx_cache, KM_NOSLEEP); int result; /* @@ -850,12 +852,13 @@ real_LZ4_compress(const char *source, char *dest, int isize, int osize) if (ctx == NULL) return (0); + bzero(ctx, sizeof(struct refTables)); if (isize < LZ4_64KLIMIT) result = LZ4_compress64kCtx(ctx, source, dest, isize, osize); else result = LZ4_compressCtx(ctx, source, dest, isize, osize); - kmem_free(ctx, sizeof (struct refTables)); + kmem_cache_free(lz4_ctx_cache, ctx); return (result); #else if (isize < (int)LZ4_64KLIMIT) @@ -1001,3 +1004,22 @@ LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize, _output_error: return (int)(-(((char *)ip) - source)); } + +extern void +lz4_init(void) +{ + +#if HEAPMODE + lz4_ctx_cache = kmem_cache_create("lz4_ctx", sizeof(struct refTables), + 0, NULL, NULL, NULL, NULL, NULL, 0); +#endif +} + +extern void +lz4_fini(void) +{ + +#if HEAPMODE + kmem_cache_destroy(lz4_ctx_cache); +#endif +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c index d92bcf0..17983bf 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c @@ -1739,6 +1739,7 @@ spa_init(int mode) unique_init(); space_map_init(); zio_init(); + lz4_init(); dmu_init(); zil_init(); vdev_cache_stat_init(); @@ -1764,6 +1765,7 @@ spa_fini(void) vdev_cache_stat_fini(); zil_fini(); dmu_fini(); + lz4_fini(); zio_fini(); space_map_fini(); unique_fini(); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_compress.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_compress.h index 85b8a99..c0be314 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_compress.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio_compress.h @@ -70,6 +70,8 @@ extern size_t zle_compress(void *src, void *dst, size_t s_len, size_t d_len, int level); extern int zle_decompress(void *src, void *dst, size_t s_len, size_t d_len, int level); +extern void lz4_init(void); +extern void lz4_fini(void); extern size_t lz4_compress(void *src, void *dst, size_t s_len, size_t d_len, int level); extern int lz4_decompress(void *src, void *dst, size_t s_len, size_t d_len, |