Re: Detection of hadware feature => please do not use signal - Mailing list pgsql-bugs
From | Tom Lane |
---|---|
Subject | Re: Detection of hadware feature => please do not use signal |
Date | |
Msg-id | 707008.1732325995@sss.pgh.pa.us Whole thread Raw |
In response to | Re: Detection of hadware feature => please do not use signal (Thomas Munro <thomas.munro@gmail.com>) |
Responses |
Re: Detection of hadware feature => please do not use signal
|
List | pgsql-bugs |
Thomas Munro <thomas.munro@gmail.com> writes: > Unfortunately it looks like NetBSD doesn't put AT_HWCAP into its > auxv[], or even expose it to user space nicely, and those libraries > don't seem to know of another way. Hopefully NetBSD will align with > those other systems for portability's sake. The only other way I > could find in a quick googling session is /usr/sbin/cpuctl, root only, > no cigar (but a solid clue that the information is floating around > somewhere, it just depends where exactly the root-only fencing is > happening). I poked into this with NetBSD and found that cpuctl's "identify" option works just fine without root. So that motivated me to dig into its source code, and I end up with the attached. Sadly it only works in 64-bit; there is presumably a way to detect this in 32-bit as well, but cpuctl doesn't know it. That doesn't bother me a whole lot though, at least not nearly as much as the 64-bit case. Anybody running PG on 32-bit ARM shouldn't be expecting great performance. I've checked this on NetBSD 9.2 and 10.0. I don't have hardware that should return false (and there may not be any such 64-bit hardware anyway...), so there's not much more I can test. regards, tom lane diff --git a/src/port/pg_crc32c_armv8_choose.c b/src/port/pg_crc32c_armv8_choose.c index 306500154e..f035ac9855 100644 --- a/src/port/pg_crc32c_armv8_choose.c +++ b/src/port/pg_crc32c_armv8_choose.c @@ -31,6 +31,11 @@ #endif #endif +#if defined(__NetBSD__) && defined(__aarch64__) +#include <sys/sysctl.h> +#include <aarch64/armreg.h> +#endif + #include "port/pg_crc32c.h" static bool @@ -52,6 +57,42 @@ pg_crc32c_armv8_available(void) #else return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0; #endif +#elif defined(__NetBSD__) && defined(__aarch64__) + /* + * On NetBSD we can read AArch64 Instruction Set Attribute Register 0 via + * sysctl. We could probably do something similar on arm32 as well, but + * it's undocumented. Note we assume cpu0 is representative of all the + * machine's CPUs. + */ + const char *path = "machdep.cpu0.cpu_id"; + size_t len; +#define SYSCTL_CPU_ID_MAXSIZE 64 + uint64 sysctlbuf[SYSCTL_CPU_ID_MAXSIZE]; + struct aarch64_sysctl_cpu_id *id = + (struct aarch64_sysctl_cpu_id *) sysctlbuf; + uint64 reg; + uint64 fld; + + len = sizeof(sysctlbuf); + memset(sysctlbuf, 0, len); + if (sysctlbyname(path, id, &len, NULL, 0) != 0) + return false; + if (len != sizeof(struct aarch64_sysctl_cpu_id)) + return false; /* kernel incompatibility? */ + +#define ISAR0_CRC32_BITPOS 16 +#define ISAR0_CRC32_BITWIDTH 4 +#define WIDTHMASK(w) ((((uint64) 1) << (w)) - 1) + + reg = id->ac_aa64isar0; + fld = (reg >> ISAR0_CRC32_BITPOS) & WIDTHMASK(ISAR0_CRC32_BITWIDTH); + + /* + * Available documentation defines only the field values 0 (No CRC32) and + * 1 (CRC32B/CRC32H/CRC32W/CRC32X/CRC32CB/CRC32CH/CRC32CW/CRC32CX). Assume + * that any future nonzero value will be a superset of 1. + */ + return (fld != 0); #else return false; #endif
pgsql-bugs by date: