Skip to content

Commit

Permalink
Redo cpuid feature detection, part 2
Browse files Browse the repository at this point in the history
Turns out using GCC cpuid() clobbers registers
with first symptoms dying in tunables. MS has
intrinsic cpuid() so we might as well use it.

Also make sure the tnable get functions use
static memory, as they are used after function
returns.

Signed-off-by: Jorgen Lundman <[email protected]>
  • Loading branch information
lundman committed Mar 18, 2024
1 parent fe2ce35 commit ad3d9f7
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 36 deletions.
36 changes: 9 additions & 27 deletions include/os/windows/spl/sys/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#define _SPL_PROCESSOR_H

#include <sys/types.h>
#include <intrin.h>

extern uint32_t getcpuid();

Expand All @@ -14,41 +15,22 @@ extern int __cpuid_count(unsigned int __level, unsigned int __sublevel,
unsigned int __eax, unsigned int __ebx,
unsigned int __ecx, unsigned int __edx);

#define __cpuid_count(level, count, a, b, c, d) \
__asm__("xchg{l}\t{%%}ebx, %1\n\t" \
"cpuid\n\t" \
"xchg{l}\t{%%}ebx, %1\n\t" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (level), "2" (count))

#define __cpuid(level, a, b, c, d) \
__asm__("xchg{l}\t{%%}ebx, %1\n\t" \
"cpuid\n\t" \
"xchg{l}\t{%%}ebx, %1\n\t" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (level))

static inline unsigned int
__get_cpuid_max(unsigned int __ext, unsigned int *__sig)
{
#ifdef _WIN32
int32_t r[4];
__cpuid(r, __ext);
if (__sig)
*__sig = (uint32_t)r[1];
return ((uint32_t)r[0]);
#else
unsigned int __eax, __ebx, __ecx, __edx;
__cpuid(__ext, __eax, __ebx, __ecx, __edx);
if (__sig)
*__sig = __ebx;
return (__eax);
}

/* macOS does have do_cpuid() macro */
static inline int
__get_cpuid(unsigned int __level,
unsigned int *__eax, unsigned int *__ebx,
unsigned int *__ecx, unsigned int *__edx)
{
unsigned int __ext = __level & 0x80000000;
if (__get_cpuid_max(__ext, 0) < __level)
return (0);
__cpuid(__level, *__eax, *__ebx, *__ecx, *__edx);
return (1);
#endif
}

#endif // x86
Expand Down
4 changes: 4 additions & 0 deletions include/os/windows/spl/sys/simd.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,12 @@ __cpuid_check_feature(const cpuid_feature_desc_t *desc)
* for AVX2. It is a macro, so return parameters
* are passed by value.
*/
#ifdef _WIN32
__cpuidex((int32_t *)r, desc->leaf, desc->subleaf);
#else
__cpuid_count(desc->leaf, desc->subleaf,
r[EAX], r[EBX], r[ECX], r[EDX]);
#endif
return ((r[desc->reg] & desc->flag) == desc->flag);
}
return (B_FALSE);
Expand Down
2 changes: 1 addition & 1 deletion module/icp/algs/blake3/blake3_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,10 @@ blake3_param_set(const char *val, zfs_kernel_param_t *unused)
int
win32_blake3_param_set(ZFS_MODULE_PARAM_ARGS)
{
static char buffer[PAGE_SIZE]; /* Looks like they use page size */
*type = ZT_TYPE_STRING;

if (set == B_FALSE) {
char buffer[PAGE_SIZE]; /* Looks like they use page size */
blake3_param_get(buffer, NULL);
*ptr = buffer;
*len = strlen(buffer);
Expand Down
8 changes: 4 additions & 4 deletions module/icp/algs/modes/gcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1031,15 +1031,15 @@ icp_gcm_impl_get(char *buffer, zfs_kernel_param_t *kp)
int
win32_icp_gcm_impl_set(ZFS_MODULE_PARAM_ARGS)
{
static char str[1024] = "";
static char buffer[PAGE_SIZE] = "";

*type = ZT_TYPE_STRING;

if (set == B_FALSE) {
if (gcm_impl_initialized)
icp_gcm_impl_get(str, NULL);
*ptr = str;
*len = strlen(str);
icp_gcm_impl_get(buffer, NULL);
*ptr = buffer;
*len = strlen(buffer);
return (0);
}

Expand Down
4 changes: 2 additions & 2 deletions module/os/windows/zfs/sysctl_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ param_set_arc_int(ZFS_MODULE_PARAM_ARGS)
int
param_set_active_allocator(ZFS_MODULE_PARAM_ARGS)
{
char buf[16];
static char buf[16];

*type = ZT_TYPE_STRING;

Expand Down Expand Up @@ -668,7 +668,7 @@ param_set_deadman_ziotime(ZFS_MODULE_PARAM_ARGS)
int
param_set_deadman_failmode(ZFS_MODULE_PARAM_ARGS)
{
char buf[16];
static char buf[16];

*type = ZT_TYPE_STRING;

Expand Down
4 changes: 2 additions & 2 deletions module/zfs/spa.c
Original file line number Diff line number Diff line change
Expand Up @@ -1485,7 +1485,7 @@ spa_taskq_write_param(ZFS_MODULE_PARAM_ARGS)
static int
win32_spa_taskq_read_param_set(ZFS_MODULE_PARAM_ARGS)
{
char str[1024] = "";
static char str[1024] = "";

*type = ZT_TYPE_STRING;

Expand All @@ -1506,7 +1506,7 @@ win32_spa_taskq_read_param_set(ZFS_MODULE_PARAM_ARGS)
static int
win32_spa_taskq_write_param_set(ZFS_MODULE_PARAM_ARGS)
{
char str[1024] = "";
static char str[1024] = "";

*type = ZT_TYPE_STRING;

Expand Down

0 comments on commit ad3d9f7

Please sign in to comment.