Skip to content

Commit

Permalink
Fix memory allocation issue for BLAKE3 context
Browse files Browse the repository at this point in the history
The kmem_alloc(sizeof (*ctx), KM_NOSLEEP) call on FreeBSD can't be
used in this code segment. Work around this by pre-allocating a percpu
context array for later use.

Reviewed-by: Ryan Moeller <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tino Reichardt <[email protected]>
Closes #13568
  • Loading branch information
mcmilk authored Jun 21, 2022
1 parent b17663f commit deb1213
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
5 changes: 5 additions & 0 deletions include/sys/blake3.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ void Blake3_Final(const BLAKE3_CTX *ctx, uint8_t *out);
void Blake3_FinalSeek(const BLAKE3_CTX *ctx, uint64_t seek, uint8_t *out,
size_t out_len);

/* these are pre-allocated contexts */
extern void **blake3_per_cpu_ctx;
extern void blake3_per_cpu_ctx_init(void);
extern void blake3_per_cpu_ctx_fini(void);

/* return number of supported implementations */
extern int blake3_get_impl_count(void);

Expand Down
28 changes: 28 additions & 0 deletions module/icp/algs/blake3/blake3_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,34 @@ blake3_impl_get_ops(void)
return (blake3_selected_impl);
}

#if defined(_KERNEL)
void **blake3_per_cpu_ctx;

void
blake3_per_cpu_ctx_init(void)
{
/*
* Create "The Godfather" ptr to hold all blake3 ctx
*/
blake3_per_cpu_ctx = kmem_alloc(max_ncpus * sizeof (void *), KM_SLEEP);
for (int i = 0; i < max_ncpus; i++) {
blake3_per_cpu_ctx[i] = kmem_alloc(sizeof (BLAKE3_CTX),
KM_SLEEP);
}
}

void
blake3_per_cpu_ctx_fini(void)
{
for (int i = 0; i < max_ncpus; i++) {
memset(blake3_per_cpu_ctx[i], 0, sizeof (BLAKE3_CTX));
kmem_free(blake3_per_cpu_ctx[i], sizeof (BLAKE3_CTX));
}
memset(blake3_per_cpu_ctx, 0, max_ncpus * sizeof (void *));
kmem_free(blake3_per_cpu_ctx, max_ncpus * sizeof (void *));
}
#endif

#if defined(_KERNEL) && defined(__linux__)
static int
icp_blake3_impl_set(const char *name, zfs_kernel_param_t *kp)
Expand Down
12 changes: 8 additions & 4 deletions module/zfs/blake3_zfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,22 @@ void
abd_checksum_blake3_native(abd_t *abd, uint64_t size, const void *ctx_template,
zio_cksum_t *zcp)
{
BLAKE3_CTX *ctx;

ctx = kmem_alloc(sizeof (*ctx), KM_NOSLEEP);
ASSERT(ctx != 0);
ASSERT(ctx_template != 0);

#if defined(_KERNEL)
BLAKE3_CTX *ctx = blake3_per_cpu_ctx[CPU_SEQID_UNSTABLE];
#else
BLAKE3_CTX *ctx = kmem_alloc(sizeof (*ctx), KM_SLEEP);
#endif

memcpy(ctx, ctx_template, sizeof (*ctx));
(void) abd_iterate_func(abd, 0, size, blake3_incremental, ctx);
Blake3_Final(ctx, (uint8_t *)zcp);

#if !defined(_KERNEL)
memset(ctx, 0, sizeof (*ctx));
kmem_free(ctx, sizeof (*ctx));
#endif
}

/*
Expand Down
7 changes: 7 additions & 0 deletions module/zfs/zfs_chksum.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ chksum_benchmark(void)
void
chksum_init(void)
{
#ifdef _KERNEL
blake3_per_cpu_ctx_init();
#endif

/* Benchmark supported implementations */
chksum_benchmark();
Expand Down Expand Up @@ -313,4 +316,8 @@ chksum_fini(void)
chksum_stat_cnt = 0;
chksum_stat_data = 0;
}

#ifdef _KERNEL
blake3_per_cpu_ctx_fini();
#endif
}

0 comments on commit deb1213

Please sign in to comment.