From f51411782edfd389b142415ab725d2ecae73fabb Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Sat, 22 Jan 2022 23:05:15 +0100 Subject: [PATCH] lz4_zfs: FreeBSD-local changes to use a custom allocator. This is not associated with a specific upstream commit but apparently a local diff applied as part of: commit e92ffd9b626833ebdbf2742c8ffddc6cd94b963e Merge: 3c3df3660072 17b2ae0b24d4 Author: Martin Matuska Date: Sat Jan 22 23:05:15 2022 +0100 zfs: merge openzfs/zfs@17b2ae0b2 (master) into main Notable upstream pull request merges: #12766 Fix error propagation from lzc_send_redacted #12805 Updated the lz4 decompressor #12851 FreeBSD: Provide correct file generation number #12857 Verify dRAID empty sectors #12874 FreeBSD: Update argument types for VOP_READDIR #12896 Reduce number of arc_prune threads #12934 FreeBSD: Fix zvol_*_open() locking #12947 lz4: Cherrypick fix for CVE-2021-3520 #12961 FreeBSD: Fix leaked strings in libspl mnttab #12964 Fix handling of errors from dmu_write_uio_dbuf() on FreeBSD #12981 Introduce a flag to skip comparing the local mac when raw sending #12985 Avoid memory allocations in the ARC eviction thread Obtained from: OpenZFS OpenZFS commit: 17b2ae0b24d487fdda2ef1098ec26fa7f79a61f6 --- module/zfs/lz4_zfs.c | 63 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/module/zfs/lz4_zfs.c b/module/zfs/lz4_zfs.c index e28215cf3501..820556effb8b 100644 --- a/module/zfs/lz4_zfs.c +++ b/module/zfs/lz4_zfs.c @@ -50,7 +50,8 @@ static int LZ4_compress64kCtx(void *ctx, const char *source, char *dest, int LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize, int maxOutputSize); -static kmem_cache_t *lz4_cache; +static void *lz4_alloc(int flags); +static void lz4_free(void *ctx); size_t lz4_compress_zfs(void *s_start, void *d_start, size_t s_len, @@ -842,8 +843,7 @@ real_LZ4_compress(const char *source, char *dest, int isize, int osize) void *ctx; int result; - ASSERT(lz4_cache != NULL); - ctx = kmem_cache_alloc(lz4_cache, KM_SLEEP); + ctx = lz4_alloc(KM_SLEEP); /* * out of kernel memory, gently fall through - this will disable @@ -859,10 +859,29 @@ real_LZ4_compress(const char *source, char *dest, int isize, int osize) else result = LZ4_compressCtx(ctx, source, dest, isize, osize); - kmem_cache_free(lz4_cache, ctx); + lz4_free(ctx); return (result); } +#ifdef __FreeBSD__ +/* + * FreeBSD has 4, 8 and 16 KB malloc zones which can be used here. + * Should struct refTables get resized this may need to be revisited, hence + * compiler-time asserts. + */ +_Static_assert(sizeof(struct refTables) <= 16384, + "refTables too big for malloc"); +_Static_assert((sizeof(struct refTables) % 4096) == 0, + "refTables not a multiple of page size"); +#else +#define ZFS_LZ4_USE_CACHE +#endif + +#ifdef ZFS_LZ4_USE_CACHE +static kmem_cache_t *lz4_cache; +#endif + +#ifdef ZFS_LZ4_USE_CACHE void lz4_init(void) { @@ -878,3 +897,39 @@ lz4_fini(void) lz4_cache = NULL; } } + +static void * +lz4_alloc(int flags) +{ + ASSERT(lz4_cache != NULL); + return (kmem_cache_alloc(lz4_cache, flags)); +} + +static void +lz4_free(void *ctx) +{ + kmem_cache_free(lz4_cache, ctx); +} +#else +void +lz4_init(void) +{ +} + +void +lz4_fini(void) +{ +} + +static void * +lz4_alloc(int flags) +{ + return (kmem_alloc(sizeof (struct refTables), flags)); +} + +static void +lz4_free(void *ctx) +{ + kmem_free(ctx, sizeof (struct refTables)); +} +#endif