opnsense-src/sys/contrib/openzfs/module/zcommon/simd_stat.c
Martin Matuska 2ec8b69480 zfs: merge openzfs/zfs@e269af1b3 (zfs-2.2-release) into stable/14
OpenZFS release 2.2.7

Notable upstream pull request merges:
 #15457 022bf8637 Increase L2ARC write rate and headroom
 #15527 1ba5b2ef8 freebsd: remove __FBSDID macro use
 #15792 9e7af55e8 Add custom debug printing for your asserts
 #15793 a1ea40af8 libzfs: use zfs_strerror() in place of strerror()
 #16181 -multiple zdb/ztest: improve and harmonise crash output
 #16208 e5e4957a5 Allow block cloning to be interrupted by a signal
 #16210 ba4e582a6 FreeBSD: Add const qualifier to members of struct
                  opensolaris_utsname
 #16225 a6198f34b Simplify issig()
 #16335 25ec9a903 zdb: fix BRT dump
 #16364 cf80a803d zvol: ensure device minors are properly cleaned up
 #16404 384b53be8 FreeBSD: Add missing memory reclamation accounting
 #16492 -multiple Split "shared" userspace & kernel code into separate files
 #16496 f1694496a zfs_file: rename zfs_file_fallocate to zfs_file_deallocate
 #16511 bc0d89bfc Fix an uninitialized data access
 #16529 2dc8529d9 Fix handling of DNS names with '-' in them for sharenfs
 #16539 30ea44296 zfs_log: add flex array fields to log record structs
 #16546 098789216 Evicting too many bytes from MFU metadata
 #16551 54278533a Reduce and handle EAGAIN errors on AIO label reads
 #16554 84ad1d536 FreeBSD: restore zfs_znode_update_vfs()
 #16565 21c40e6d9 FreeBSD: Sync taskq_cancel_id() returns with Linux
 #16567 48482bb2f Properly release key in spa_keystore_dsl_key_hold_dd()
 #16584 e8f4592a1 Avoid computing strlen() inside loops
 #16605 acc8a3186 ARC: Cache arc_c value during arc_evict()
 #16650 fc60e0c6e freebsd: Use compiler.h from FreeBSD's base's linuxkpi
 #16667 b32b35cea zdb: show bp in uberblock dump
 #16684 1f5e1b919 Pack dmu_buf_impl_t by 16 bytes
 #16688 73b3e8ace Fix gcc uninitialized warning in FreeBSD zio_crypt.c
 #16690 727506c94 On the first vdev open ignore impossible ashift hints
 #16692 d83cd5307 zdb: add extra -T flag to show histograms of BRT refcounts
 #16693 82ab837a0 Fix gcc unused value warning in FreeBSD simd.h
 #16740 2bba6e3c5 BRT: Don't call brt_pending_remove() on holes/embedded
 #16801 299da6ace Fix race in libzfs_run_process_impl

Obtained from:	OpenZFS
OpenZFS commit: e269af1b3c
OpenZFS tag:	zfs-2.2.7
2024-12-12 13:22:56 +01:00

203 lines
6.6 KiB
C

/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2024 Google, Inc. All rights reserved.
*/
#include <sys/zfs_context.h>
#include <sys/kstat.h>
#include <sys/simd.h>
#ifdef _KERNEL
#ifdef __linux__
#include <linux/simd.h>
#endif /* __linux__ */
kstat_t *simd_stat_kstat;
#endif /* _KERNEL */
#ifdef _KERNEL
/* Sometimes, we don't define these at all. */
#ifndef HAVE_KERNEL_FPU
#define HAVE_KERNEL_FPU (0)
#endif
#ifndef HAVE_KERNEL_NEON
#define HAVE_KERNEL_NEON (0)
#endif
#ifndef HAVE_KERNEL_FPU_INTERNAL
#define HAVE_KERNEL_FPU_INTERNAL (0)
#endif
#ifndef HAVE_UNDERSCORE_KERNEL_FPU
#define HAVE_UNDERSCORE_KERNEL_FPU (0)
#endif
#define SIMD_STAT_PRINT(s, feat, val) \
kmem_scnprintf(s + off, MAX(4095-off, 0), "%-16s\t%1d\n", feat, (val))
static int
simd_stat_kstat_data(char *buf, size_t size, void *data)
{
(void) data;
static char simd_stat_kstat_payload[4096] = {0};
static int off = 0;
#ifdef __linux__
if (off == 0) {
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"kfpu_allowed", kfpu_allowed());
#if defined(__x86_64__) || defined(__i386__)
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"kfpu", HAVE_KERNEL_FPU);
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"kfpu_internal", HAVE_KERNEL_FPU_INTERNAL);
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"__kernel_fpu", HAVE_UNDERSCORE_KERNEL_FPU);
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"sse", zfs_sse_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"sse2", zfs_sse2_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"sse3", zfs_sse3_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"ssse3", zfs_ssse3_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"sse41", zfs_sse4_1_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"sse42", zfs_sse4_2_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx", zfs_avx_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx2", zfs_avx2_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx512f", zfs_avx512f_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx512cd", zfs_avx512cd_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx512er", zfs_avx512er_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx512pf", zfs_avx512pf_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx512bw", zfs_avx512bw_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx512dq", zfs_avx512dq_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx512vl", zfs_avx512vl_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx512ifma", zfs_avx512ifma_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"avx512vbmi", zfs_avx512vbmi_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"ymm", __ymm_enabled());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"zmm", __zmm_enabled());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"bmi1", zfs_bmi1_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"bmi2", zfs_bmi2_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"aes", zfs_aes_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"pclmulqdq", zfs_pclmulqdq_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"movbe", zfs_movbe_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"osxsave", boot_cpu_has(X86_FEATURE_OSXSAVE));
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"xsaves", static_cpu_has(X86_FEATURE_XSAVES));
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"xsaveopt", static_cpu_has(X86_FEATURE_XSAVEOPT));
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"xsave", static_cpu_has(X86_FEATURE_XSAVE));
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"fxsr", static_cpu_has(X86_FEATURE_FXSR));
#endif /* __x86__ */
#if defined(__arm__) || defined(__aarch64__)
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"kernel_neon", HAVE_KERNEL_NEON);
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"kernel_mode_neon", CONFIG_KERNEL_MODE_NEON);
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"neon", zfs_neon_available());
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"sha256", zfs_sha256_available());
#if defined(__aarch64__)
/*
* This technically can exist on 32b ARM but we don't
* define hooks to check for it and I didn't want to
* learn enough ARM ASM to add one.
*/
off += SIMD_STAT_PRINT(simd_stat_kstat_payload,
"sha512", zfs_sha512_available());
#endif /* __aarch64__ */
#endif /* __arm__ */
/* We want to short-circuit this on unsupported platforms. */
off += 1;
}
kmem_scnprintf(buf, MIN(off, size), "%s", simd_stat_kstat_payload);
#endif /* __linux__ */
return (0);
}
#endif /* _KERNEL */
void
simd_stat_init(void)
{
static boolean_t simd_stat_initialized = B_FALSE;
if (!simd_stat_initialized) {
#if defined(_KERNEL)
/* Install kstats for all implementations */
simd_stat_kstat = kstat_create("zfs", 0, "simd", "misc",
KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
if (simd_stat_kstat != NULL) {
simd_stat_kstat->ks_data = (void*)(uintptr_t)1;
simd_stat_kstat->ks_ndata = 1;
simd_stat_kstat->ks_flags |= KSTAT_FLAG_NO_HEADERS;
kstat_set_raw_ops(simd_stat_kstat,
NULL,
simd_stat_kstat_data,
NULL);
kstat_install(simd_stat_kstat);
}
#endif /* _KERNEL */
}
/* Finish initialization */
simd_stat_initialized = B_TRUE;
}
void
simd_stat_fini(void)
{
#if defined(_KERNEL)
if (simd_stat_kstat != NULL) {
kstat_delete(simd_stat_kstat);
simd_stat_kstat = NULL;
}
#endif
}
#ifdef _KERNEL
EXPORT_SYMBOL(simd_stat_init);
EXPORT_SYMBOL(simd_stat_fini);
#endif