Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tEf8C-008tYO-NF for pgsql-bugs@arkaria.postgresql.org; Sat, 23 Nov 2024 01:40:16 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tEf8B-00EM5h-7g for pgsql-bugs@arkaria.postgresql.org; Sat, 23 Nov 2024 01:40:15 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tEf8A-00EM5Z-VO for pgsql-bugs@lists.postgresql.org; Sat, 23 Nov 2024 01:40:14 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tEf88-003MwN-B9 for pgsql-bugs@lists.postgresql.org; Sat, 23 Nov 2024 01:40:14 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 4AN1dtVi707009; Fri, 22 Nov 2024 20:39:55 -0500 From: Tom Lane To: Thomas Munro cc: Heikki Linnakangas , =?UTF-8?Q?Bastien_Roucari=C3=A8s?= , pgsql-bugs@lists.postgresql.org Subject: Re: Detection of hadware feature => please do not use signal In-reply-to: References: <4496616.iHFcN1HehY@portable-bastien> <1156374.1730396928@sss.pgh.pa.us> <7ec1c65c-1a28-49a7-af43-f77c260a3df6@iki.fi> <1292593.1730399134@sss.pgh.pa.us> Comments: In-reply-to Thomas Munro message dated "Fri, 01 Nov 2024 17:28:53 +1300" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <706981.1732325974.0@sss.pgh.pa.us> Date: Fri, 22 Nov 2024 20:39:55 -0500 Message-ID: <707008.1732325995@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <706981.1732325974.1@sss.pgh.pa.us> Thomas Munro 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 ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="netbsd-arm-crc-detection.patch"; charset="us-ascii" Content-ID: <706981.1732325974.2@sss.pgh.pa.us> Content-Description: netbsd-arm-crc-detection.patch Content-Transfer-Encoding: quoted-printable 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 +#include +#endif + #include "port/pg_crc32c.h" = static bool @@ -52,6 +57,42 @@ pg_crc32c_armv8_available(void) #else return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) !=3D 0; #endif +#elif defined(__NetBSD__) && defined(__aarch64__) + /* + * On NetBSD we can read AArch64 Instruction Set Attribute Register 0 vi= a + * 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 =3D "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 =3D + (struct aarch64_sysctl_cpu_id *) sysctlbuf; + uint64 reg; + uint64 fld; + + len =3D sizeof(sysctlbuf); + memset(sysctlbuf, 0, len); + if (sysctlbyname(path, id, &len, NULL, 0) !=3D 0) + return false; + if (len !=3D 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 =3D id->ac_aa64isar0; + fld =3D (reg >> ISAR0_CRC32_BITPOS) & WIDTHMASK(ISAR0_CRC32_BITWIDTH); + + /* + * Available documentation defines only the field values 0 (No CRC32) an= d + * 1 (CRC32B/CRC32H/CRC32W/CRC32X/CRC32CB/CRC32CH/CRC32CW/CRC32CX). Assu= me + * that any future nonzero value will be a superset of 1. + */ + return (fld !=3D 0); #else return false; #endif ------- =_aaaaaaaaaa0--