• Palmer Dabbelt's avatar
    Merge patch series "RISC-V Hardware Probing User Interface" · eb04e72b
    Palmer Dabbelt authored
    Evan Green <evan@rivosinc.com> says:
    
    There's been a bunch of off-list discussions about this, including at
    Plumbers.  The original plan was to do something involving providing an
    ISA string to userspace, but ISA strings just aren't sufficient for a
    stable ABI any more: in order to parse an ISA string users need the
    version of the specifications that the string is written to, the version
    of each extension (sometimes at a finer granularity than the RISC-V
    releases/versions encode), and the expected use case for the ISA string
    (ie, is it a U-mode or M-mode string).  That's a lot of complexity to
    try and keep ABI compatible and it's probably going to continue to grow,
    as even if there's no more complexity in the specifications we'll have
    to deal with the various ISA string parsing oddities that end up all
    over userspace.
    
    Instead this patch set takes a very different approach and provides a set
    of key/value pairs that encode various bits about the system.  The big
    advantage here is that we can clearly define what these mean so we can
    ensure ABI stability, but it also allows us to encode information that's
    unlikely to ever appear in an ISA string (see the misaligned access
    performance, for example).  The resulting interface looks a lot like
    what arm64 and x86 do, and will hopefully fit well into something like
    ACPI in the future.
    
    The actual user interface is a syscall, with a vDSO function in front of
    it. The vDSO function can answer some queries without a syscall at all,
    and falls back to the syscall for cases it doesn't have answers to.
    Currently we prepopulate it with an array of answers for all keys and
    a CPU set of "all CPUs". This can be adjusted as necessary to provide
    fast answers to the most common queries.
    
    An example series in glibc exposing this syscall and using it in an
    ifunc selector for memcpy can be found at [1].
    
    I was asked about the performance delta between this and something like
    sysfs. I created a small test program and ran it on a Nezha D1
    Allwinner board. Doing each operation 100000 times and dividing, these
    operations take the following amount of time:
     - open()+read()+close() of /sys/kernel/cpu_byteorder: 3.8us
     - access("/sys/kernel/cpu_byteorder", R_OK): 1.3us
     - riscv_hwprobe() vDSO and syscall: .0094us
     - riscv_hwprobe() vDSO with no syscall: 0.0091us
    
    These numbers get farther apart if we query multiple keys, as sysfs will
    scale linearly with the number of keys, where the dedicated syscall
    stays the same. To frame these numbers, I also did a tight
    fork/exec/wait loop, which I measured as 4.8ms. So doing 4
    open/read/close operations is a delta of about 0.3%, versus a single vDSO
    call is a delta of essentially zero.
    
    [1] https://patchwork.ozlabs.org/project/glibc/list/?series=343050
    
    * b4-shazam-merge:
      RISC-V: Add hwprobe vDSO function and data
      selftests: Test the new RISC-V hwprobe interface
      RISC-V: hwprobe: Support probing of misaligned access performance
      RISC-V: hwprobe: Add support for RISCV_HWPROBE_BASE_BEHAVIOR_IMA
      RISC-V: Add a syscall for HW probing
      RISC-V: Move struct riscv_cpuinfo to new header
    
    Link: https://lore.kernel.org/r/20230407231103.2622178-1-evan@rivosinc.comSigned-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
    eb04e72b
cpu.c 8.44 KB