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:

Previous
From: PG Bug reporting form
Date:
Subject: BUG #18720: Can not install
Next
From: PG Bug reporting form
Date:
Subject: BUG #18721: Documentation for psql does not specify that the history feature doesn't work