diff --git a/SPECS/ceph/1000-arch-add-riscv-crc32c-support.patch b/SPECS/ceph/1000-arch-add-riscv-crc32c-support.patch new file mode 100644 index 0000000000..3f5f423199 --- /dev/null +++ b/SPECS/ceph/1000-arch-add-riscv-crc32c-support.patch @@ -0,0 +1,464 @@ +From 01dc12ad5651f0957a0b46cd311a7ab8e7100d86 Mon Sep 17 00:00:00 2001 +From: lvshuo2016 +Date: Wed, 22 Oct 2025 18:09:52 +0800 +Subject: [PATCH] common,arch,cmake: add RISC-V crc32c support + +This adds hardware-accelerated crc32c support for the RISC-V +architecture. It includes the feature implementation, necessary +CMake configuration, and plumbing in src/arch/riscv.c to correctly +detect and select the optimized instructions. + +Signed-off-by: lvshuo2016 +--- + cmake/modules/SIMDExt.cmake | 20 ++++ + src/arch/CMakeLists.txt | 2 + + src/arch/probe.cc | 3 + + src/arch/riscv.c | 36 +++++++ + src/arch/riscv.h | 26 +++++ + src/common/CMakeLists.txt | 5 + + src/common/crc32c.cc | 6 ++ + src/common/crc32c_riscv.c | 188 ++++++++++++++++++++++++++++++++++ + src/common/crc32c_riscv.h | 29 ++++++ + src/include/config-h.in.cmake | 6 ++ + 10 files changed, 321 insertions(+) + create mode 100644 src/arch/riscv.c + create mode 100644 src/arch/riscv.h + create mode 100644 src/common/crc32c_riscv.c + create mode 100644 src/common/crc32c_riscv.h + +diff --git a/cmake/modules/SIMDExt.cmake b/cmake/modules/SIMDExt.cmake +index 35b52e64200b7..d72998b1ac6b2 100644 +--- a/cmake/modules/SIMDExt.cmake ++++ b/cmake/modules/SIMDExt.cmake +@@ -109,6 +109,26 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(powerpc|ppc)") + if(HAVE_POWER8) + message(STATUS " HAVE_POWER8 yes") + endif() ++elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv64|RISCV64") ++ set(HAVE_RISCV 1) ++ include(CheckCCompilerFlag) ++ ++ CHECK_C_COMPILER_FLAG("-march=rv64gcv_zbc_zvbc" HAVE_RISCV_ZVBC) ++ if(HAVE_RISCV_ZVBC) ++ set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -march=rv64gcv_zbc_zvbc") ++ set(HAVE_RISCV_RVV TRUE) ++ set(HAVE_RISCV_ZVBC TRUE) ++ message(STATUS " RISC-V Extension: Vector + Zbc + Zvbc detected (Best for CRC32)") ++ else() ++ CHECK_C_COMPILER_FLAG("-march=rv64gcv" HAVE_RISCV_RVV_ONLY) ++ if(HAVE_RISCV_RVV_ONLY) ++ set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -march=rv64gcv") ++ set(HAVE_RISCV_RVV TRUE) ++ message(STATUS " RISC-V Extension: Standard Vector (rv64gcv) detected") ++ else() ++ message(WARNING " RISC-V Vector extension NOT detected by compiler.") ++ endif() ++ endif() + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(s390x|S390X|s390|S390)") + set(HAVE_S390X 1) + message(STATUS " we are s390x") +diff --git a/src/arch/CMakeLists.txt b/src/arch/CMakeLists.txt +index e95d9bbb81fa8..35c67b81210ca 100644 +--- a/src/arch/CMakeLists.txt ++++ b/src/arch/CMakeLists.txt +@@ -7,6 +7,8 @@ elseif(HAVE_INTEL) + list(APPEND arch_srcs intel.c) + elseif(HAVE_PPC64LE OR HAVE_PPC64 OR HAVE_PPC) + list(APPEND arch_srcs ppc.c) ++elseif(HAVE_RISCV) ++ list(APPEND arch_srcs riscv.c) + elseif(HAVE_S390X) + list(APPEND arch_srcs s390x.c) + endif() +diff --git a/src/arch/probe.cc b/src/arch/probe.cc +index 2189fd68dfb39..fe050921cd34f 100644 +--- a/src/arch/probe.cc ++++ b/src/arch/probe.cc +@@ -7,6 +7,7 @@ + #include "arch/arm.h" + #include "arch/ppc.h" + #include "arch/s390x.h" ++#include "arch/riscv.h" + + int ceph_arch_probe(void) + { +@@ -18,6 +19,8 @@ int ceph_arch_probe(void) + ceph_arch_arm_probe(); + #elif defined(__powerpc__) || defined(__ppc__) + ceph_arch_ppc_probe(); ++#elif defined(__riscv) ++ ceph_arch_riscv_probe(); + #elif defined(__s390__) + ceph_arch_s390x_probe(); + #endif +diff --git a/src/arch/riscv.c b/src/arch/riscv.c +new file mode 100644 +index 0000000000000..d7c306c6e16ab +--- /dev/null ++++ b/src/arch/riscv.c +@@ -0,0 +1,36 @@ ++/** ++ * Runtime detection of RISC-V vector crypto support. ++ */ ++ ++#include ++#include ++#include ++ ++int ceph_arch_riscv_zbc = 0; ++int ceph_arch_riscv_zvbc = 0; ++ ++#ifndef RISCV_HWPROBE_EXT_ZBC ++#define RISCV_HWPROBE_EXT_ZBC (1ULL << 15) ++#endif ++ ++#ifndef RISCV_HWPROBE_EXT_ZVBC ++#define RISCV_HWPROBE_EXT_ZVBC (1ULL << 20) ++#endif ++ ++static int do_hwprobe(struct riscv_hwprobe *pairs, size_t count) ++{ ++ return syscall(__NR_riscv_hwprobe, pairs, count, 0, NULL, 0); ++} ++ ++void ceph_arch_riscv_probe(void) ++{ ++ struct riscv_hwprobe pairs[] = { ++ { .key = RISCV_HWPROBE_KEY_IMA_EXT_0 }, ++ }; ++ ++ if (do_hwprobe(pairs, 1) == 0) { ++ unsigned long long ext = pairs[0].value; ++ ceph_arch_riscv_zbc = (ext & RISCV_HWPROBE_EXT_ZBC); ++ ceph_arch_riscv_zvbc = (ext & RISCV_HWPROBE_EXT_ZVBC); ++ } ++} +diff --git a/src/arch/riscv.h b/src/arch/riscv.h +new file mode 100644 +index 0000000000000..2f90cb24c1d9e +--- /dev/null ++++ b/src/arch/riscv.h +@@ -0,0 +1,26 @@ ++/* ++ * Copyright 2025 sanechips Corporation ++ * ++ * This is free software; you can redistribute it and/or modify it under the ++ * terms of the GNU Lesser General Public License version 2.1, as published by ++ * the Free Software Foundation. See file COPYING. ++ */ ++ ++#ifndef CEPH_ARCH_RISCV_H ++#define CEPH_ARCH_RISCV_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++extern int ceph_arch_riscv_zbc; ++extern int ceph_arch_riscv_zvbc; ++ ++extern void ceph_arch_riscv_probe(void); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif ++ +diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt +index 22ea30bf88f60..f25625f389df1 100644 +--- a/src/common/CMakeLists.txt ++++ b/src/common/CMakeLists.txt +@@ -255,6 +255,8 @@ elseif(HAVE_S390X) + crc32c_s390x.c + crc32c_s390x_le-vx.S + ) ++elseif(HAVE_RISCV_ZVBC) ++ list(APPEND crc32_srcs crc32c_riscv.c) + endif(HAVE_INTEL) + + add_library(crc32 OBJECT ${crc32_srcs}) +@@ -263,6 +265,9 @@ if(HAVE_ARMV8_CRC) + set_target_properties(crc32 PROPERTIES + COMPILE_FLAGS "${CMAKE_C_FLAGS} ${ARMV8_CRC_COMPILE_FLAGS}") + endif() ++if(HAVE_RISCV) ++ set_target_properties(crc32 PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} ${SIMD_COMPILE_FLAGS}") ++endif() + target_link_libraries(crc32 + arch) + +diff --git a/src/common/crc32c.cc b/src/common/crc32c.cc +index 7ef99467b347d..761bd2cd52ab1 100644 +--- a/src/common/crc32c.cc ++++ b/src/common/crc32c.cc +@@ -7,11 +7,13 @@ + #include "arch/arm.h" + #include "arch/ppc.h" + #include "arch/s390x.h" ++#include "arch/riscv.h" + #include "common/sctp_crc32.h" + #include "common/crc32c_intel_fast.h" + #include "common/crc32c_aarch64.h" + #include "common/crc32c_ppc.h" + #include "common/crc32c_s390x.h" ++#include "common/crc32c_riscv.h" + + /* + * choose best implementation based on the CPU architecture. +@@ -41,6 +43,10 @@ ceph_crc32c_func_t ceph_choose_crc32(void) + if (ceph_arch_ppc_crc32) { + return ceph_crc32c_ppc; + } ++#elif defined(__riscv) && defined(HAVE_RISCV_ZVBC) ++ if (ceph_arch_riscv_zbc && ceph_arch_riscv_zvbc) { ++ return ceph_crc32c_riscv; ++ } + #elif defined(__s390__) + if (ceph_arch_s390x_crc32) { + return ceph_crc32c_s390x; +diff --git a/src/common/crc32c_riscv.c b/src/common/crc32c_riscv.c +new file mode 100644 +index 0000000000000..a03e967b32129 +--- /dev/null ++++ b/src/common/crc32c_riscv.c +@@ -0,0 +1,188 @@ ++/* Copyright (C) 2025 sanechips Technologies Co., Ltd. ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++#include ++#include ++#include "common/sctp_crc32.h" ++#include "common/likely.h" ++ ++// CRC32C polynomial constants ++#define CRC32C_CONST_0 0xdd45aab8U ++#define CRC32C_CONST_1 0x493c7d27U ++#define CRC32C_CONST_QUO 0x0dea713f1ULL ++#define CRC32C_CONST_POLY 0x105ec76f1ULL ++ ++// Folding constants for CRC32C ++static const uint64_t crc32c_fold_const[4] __attribute__((aligned(16))) = { ++ 0x00000000740eef02ULL, 0x000000009e4addf8ULL, ++ 0x00000000f20c0dfeULL, 0x00000000493c7d27ULL ++}; ++ ++/** ++ * Hardware-accelerated CRC32C using RISC-V vector crypto extensions. ++ * This uses the reflected polynomial version compatible with standard CRC32C. ++ */ ++uint32_t ceph_crc32c_riscv(uint32_t crc, unsigned char const *buf, unsigned len) { ++ if (unlikely(len < 64) || unlikely(!buf)) { ++ // Fall back to table-based implementation for small buffers ++ return ceph_crc32c_sctp(crc, buf, len); ++ } ++ ++ uint32_t result; ++ const uint64_t *fold_consts = crc32c_fold_const; ++ uint64_t tmp_buf[2] __attribute__((aligned(16))); ++ ++ __asm__ __volatile__( ++ // Initialize CRC ++ "li t5, 0xffffffff\n\t" ++ "and %[crc], %[crc], t5\n\t" ++ "li a3, 0\n\t" ++ "li t1, 64\n\t" ++ ++ // Set vector configuration for 128-bit elements ++ "vsetivli zero, 2, e64, m1, ta, ma\n\t" ++ ++ // Load first 64 bytes and initialize ++ "mv a4, %[buf]\n\t" ++ "vle64.v v0, 0(a4)\n\t" ++ "addi a4, a4, 16\n\t" ++ "vle64.v v1, 0(a4)\n\t" ++ "addi a4, a4, 16\n\t" ++ "vle64.v v2, 0(a4)\n\t" ++ "addi a4, a4, 16\n\t" ++ "vle64.v v3, 0(a4)\n\t" ++ "addi a4, a4, 16\n\t" ++ "andi a3, %[len], ~63\n\t" ++ "addi t0, a3, -64\n\t" ++ ++ // XOR initial CRC into first vector ++ "vmv.s.x v4, zero\n\t" ++ "vmv.s.x v5, %[crc]\n\t" ++ "vslideup.vi v5, v4, 1\n\t" ++ "vxor.vv v0, v0, v5\n\t" ++ "vmv.s.x v8, zero\n\t" ++ ++ // Load folding constant ++ "add a5, a4, t0\n\t" ++ "mv t4, %[consts]\n\t" ++ "vle64.v v5, 0(t4)\n\t" ++ ++ // Check if we need main loop ++ "addi t0, %[len], -64\n\t" ++ "bltu t0, t1, 2f\n\t" ++ ++ // Main loop - process 64 bytes at a time ++ "1:\n\t" ++ "vle64.v v7, 0(a4)\n\t" ++ "vclmul.vv v4, v0, v5\n\t" ++ "vclmulh.vv v0, v0, v5\n\t" ++ "vredxor.vs v0, v0, v8\n\t" ++ "vredxor.vs v4, v4, v8\n\t" ++ "vslideup.vi v4, v0, 1\n\t" ++ "vxor.vv v0, v4, v7\n\t" ++ ++ "addi a4, a4, 16\n\t" ++ "vle64.v v7, 0(a4)\n\t" ++ "vclmul.vv v4, v1, v5\n\t" ++ "vclmulh.vv v1, v1, v5\n\t" ++ "vredxor.vs v1, v1, v8\n\t" ++ "vredxor.vs v4, v4, v8\n\t" ++ "vslideup.vi v4, v1, 1\n\t" ++ "vxor.vv v1, v4, v7\n\t" ++ ++ "addi a4, a4, 16\n\t" ++ "vle64.v v7, 0(a4)\n\t" ++ "vclmul.vv v4, v2, v5\n\t" ++ "vclmulh.vv v2, v2, v5\n\t" ++ "vredxor.vs v2, v2, v8\n\t" ++ "vredxor.vs v4, v4, v8\n\t" ++ "vslideup.vi v4, v2, 1\n\t" ++ "vxor.vv v2, v4, v7\n\t" ++ ++ "addi a4, a4, 16\n\t" ++ "vle64.v v7, 0(a4)\n\t" ++ "vclmul.vv v4, v3, v5\n\t" ++ "vclmulh.vv v3, v3, v5\n\t" ++ "vredxor.vs v3, v3, v8\n\t" ++ "vredxor.vs v4, v4, v8\n\t" ++ "vslideup.vi v4, v3, 1\n\t" ++ "vxor.vv v3, v4, v7\n\t" ++ ++ "addi a4, a4, 16\n\t" ++ "bne a4, a5, 1b\n\t" ++ ++ // Fold 512 bits to 128 bits ++ "2:\n\t" ++ "addi t4, t4, 16\n\t" ++ "vle64.v v5, 0(t4)\n\t" ++ "vclmul.vv v6, v0, v5\n\t" ++ "vclmulh.vv v7, v0, v5\n\t" ++ "vredxor.vs v6, v6, v8\n\t" ++ "vredxor.vs v7, v7, v8\n\t" ++ "vslideup.vi v6, v7, 1\n\t" ++ "vxor.vv v0, v6, v1\n\t" ++ ++ "vclmul.vv v6, v0, v5\n\t" ++ "vclmulh.vv v7, v0, v5\n\t" ++ "vredxor.vs v6, v6, v8\n\t" ++ "vredxor.vs v7, v7, v8\n\t" ++ "vslideup.vi v6, v7, 1\n\t" ++ "vxor.vv v0, v6, v2\n\t" ++ ++ "vclmul.vv v6, v0, v5\n\t" ++ "vclmulh.vv v7, v0, v5\n\t" ++ "vredxor.vs v6, v6, v8\n\t" ++ "vredxor.vs v7, v7, v8\n\t" ++ "vslideup.vi v6, v7, 1\n\t" ++ "vxor.vv v0, v6, v3\n\t" ++ ++ // Extract 128-bit result from vector register ++ "vse64.v v0, (%[tmp_ptr])\n\t" ++ "ld t0, 0(%[tmp_ptr])\n\t" ++ "ld t1, 8(%[tmp_ptr])\n\t" ++ ++ // Barrett reduction ++ "li t2, %[const0]\n\t" ++ "and t2, t2, t5\n\t" ++ "li t3, %[const1]\n\t" ++ ++ "clmul t4, t0, t3\n\t" ++ "clmulh t3, t0, t3\n\t" ++ "xor t1, t1, t4\n\t" ++ "and t4, t1, t5\n\t" ++ "srli t1, t1, 32\n\t" ++ "clmul t0, t4, t2\n\t" ++ "slli t3, t3, 32\n\t" ++ "xor t3, t3, t1\n\t" ++ "xor t3, t3, t0\n\t" ++ ++ // Final Barrett reduction ++ "and t4, t3, t5\n\t" ++ "li t2, %[quo]\n\t" ++ "li t1, %[poly]\n\t" ++ "clmul t4, t4, t2\n\t" ++ "and t4, t4, t5\n\t" ++ "clmul t4, t4, t1\n\t" ++ "xor t4, t3, t4\n\t" ++ "srai %[result], t4, 32\n\t" ++ "and %[result], %[result], t5\n\t" ++ ++ : [result] "=r" (result),[crc] "+r" (crc) ++ : [buf] "r" (buf), [len] "r" (len), [consts] "r" (fold_consts), ++ [const0] "i" (CRC32C_CONST_0), [const1] "i" (CRC32C_CONST_1), ++ [quo] "i" (CRC32C_CONST_QUO), [poly] "i" (CRC32C_CONST_POLY), ++ [tmp_ptr] "r" (tmp_buf) ++ : "a3", "a4", "a5", "t0", "t1", "t2", "t3", "t4", "t5", "v0", "v1", "v2", "v3", ++ "v4", "v5", "v6", "v7", "v8", "memory" ++ ); ++ size_t tail_len = len % 64; ++ if (tail_len > 0) { ++ result = ceph_crc32c_sctp(result, buf + len - tail_len, tail_len); ++ } ++ return result; ++} +diff --git a/src/common/crc32c_riscv.h b/src/common/crc32c_riscv.h +new file mode 100644 +index 0000000000000..092c266113c39 +--- /dev/null ++++ b/src/common/crc32c_riscv.h +@@ -0,0 +1,29 @@ ++/* Copyright (C) 2025 sanechips Technologies Co., Ltd. ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++#ifndef CEPH_COMMON_CRC32C_RISCV_H ++#define CEPH_COMMON_CRC32C_RISCV_H ++ ++#include ++ ++#if defined(__riscv) && defined(HAVE_RISCV_ZVBC) ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++extern uint32_t ceph_crc32c_riscv(uint32_t crc, unsigned char const *buffer, unsigned len); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif ++ ++#endif ++ +diff --git a/src/include/config-h.in.cmake b/src/include/config-h.in.cmake +index 7285210c7b1a5..039b62a29d223 100644 +--- a/src/include/config-h.in.cmake ++++ b/src/include/config-h.in.cmake +@@ -295,6 +295,12 @@ + /* Support ARMv8 CRC and CRYPTO intrinsics */ + #cmakedefine HAVE_ARMV8_CRC_CRYPTO_INTRINSICS + ++/* Define if you have RISC-V Vector extension */ ++#cmakedefine HAVE_RISCV_RVV 1 ++ ++/* Define if you have RISC-V ZVBC extension */ ++#cmakedefine HAVE_RISCV_ZVBC 1 ++ + /* Define if you have struct stat.st_mtimespec.tv_nsec */ + #cmakedefine HAVE_STAT_ST_MTIMESPEC_TV_NSEC diff --git a/SPECS/ceph/1001-arch-riscv-fix-hwprobe.patch b/SPECS/ceph/1001-arch-riscv-fix-hwprobe.patch new file mode 100644 index 0000000000..a21a364939 --- /dev/null +++ b/SPECS/ceph/1001-arch-riscv-fix-hwprobe.patch @@ -0,0 +1,63 @@ +From 3ccfff1acd6fa5babc7de035271b7f91fccabb8c Mon Sep 17 00:00:00 2001 +From: WenLei +Date: Fri, 27 Mar 2026 16:40:14 +0800 +Subject: [PATCH] src/arch: fix hwprobe include path and ZBC/ZVBC offsets for + riscv64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: WenLei + +Fix runtime detection of RISC-V ZBC and ZVBC crypto extensions. + +Problems fixed: +- only exists in glibc >= 2.40 (released 2024-07-22). + Many production RISC-V distros still use older glibc (Ubuntu 22.04: 2.35, + Debian 12: 2.36, etc.) and would fail to compile. + Therefore we switch to the kernel UAPI header , + which works with all current glibc versions. + Proof: + - Absent in glibc 2.39: + https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/riscv/sys/hwprobe.h;hb=refs/tags/glibc-2.39 + - Present in glibc 2.40: + https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/riscv/sys/hwprobe.h;hb=refs/tags/glibc-2.40 + - Introducing commit: + https://sourceware.org/git/?p=glibc.git;a=commit;h=426d0e1aa8f17426d13707594111df712d2b8911 + +- Incorrect fallback bit positions: + - RISCV_HWPROBE_EXT_ZBC was (1ULL << 15) → should be (1ULL << 7) + - RISCV_HWPROBE_EXT_ZVBC was (1ULL << 20) → should be (1ULL << 18) + +Signed-off-by: WenLei +--- + src/arch/riscv.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/arch/riscv.c b/src/arch/riscv.c +index d7c306c6e16ab..90ab9cb872c70 100644 +--- a/src/arch/riscv.c ++++ b/src/arch/riscv.c +@@ -2,7 +2,7 @@ + * Runtime detection of RISC-V vector crypto support. + */ + +-#include ++#include + #include + #include + +@@ -10,11 +10,11 @@ int ceph_arch_riscv_zbc = 0; + int ceph_arch_riscv_zvbc = 0; + + #ifndef RISCV_HWPROBE_EXT_ZBC +-#define RISCV_HWPROBE_EXT_ZBC (1ULL << 15) ++#define RISCV_HWPROBE_EXT_ZBC (1ULL << 7) + #endif + + #ifndef RISCV_HWPROBE_EXT_ZVBC +-#define RISCV_HWPROBE_EXT_ZVBC (1ULL << 20) ++#define RISCV_HWPROBE_EXT_ZVBC (1ULL << 18) + #endif + + static int do_hwprobe(struct riscv_hwprobe *pairs, size_t count) diff --git a/SPECS/ceph/1002-src-common-Formatter.h-cstdint.patch b/SPECS/ceph/1002-src-common-Formatter.h-cstdint.patch new file mode 100644 index 0000000000..301888f517 --- /dev/null +++ b/SPECS/ceph/1002-src-common-Formatter.h-cstdint.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] common: add missing include in Formatter.h + +Formatter.h uses `uint64_t` but relies on transitive includes, which +breaks with gcc 16's libstdc++. Fixed upstream + +Signed-off-by: Sun Yuechi +--- + src/common/Formatter.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/common/Formatter.h b/src/common/Formatter.h +index 05814ec66..cba1d4238 100644 +--- a/src/common/Formatter.h ++++ b/src/common/Formatter.h +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + + namespace ceph { diff --git a/SPECS/ceph/1003-mds-qualify-make_message.patch b/SPECS/ceph/1003-mds-qualify-make_message.patch new file mode 100644 index 0000000000..1c331e56b1 --- /dev/null +++ b/SPECS/ceph/1003-mds-qualify-make_message.patch @@ -0,0 +1,84 @@ +From ea218daf73965fdaee54693bbfcd675c031992f9 Mon Sep 17 00:00:00 2001 +From: "Adam C. Emerson" +Date: Wed, 21 Jan 2026 17:31:23 -0500 +Subject: [PATCH] mds: Fully qualify some calls to `make_message` + +`crimson::make_message` participates in some of the same overloads as +`ceph::make_message` and GCC 16 looks to be doing ADL differently than +GCC 15. + +(Also fix the indentation on `reply_client_request`.) + +Signed-off-by: Adam C. Emerson +--- + src/mds/Locker.cc | 2 +- + src/mds/MDCache.cc | 2 +- + src/mds/Server.cc | 8 ++++---- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc +index 58305db60683b..2cb92de118138 100644 +--- a/src/mds/Locker.cc ++++ b/src/mds/Locker.cc +@@ -4501,7 +4501,7 @@ void Locker::handle_client_lease(const cref_t &m) + dout(7) << "handle_client_lease client." << client << " renew on " << *dn + << (!dn->lock.can_lease(client)?", revoking lease":"") << dendl; + if (dn->lock.can_lease(client)) { +- auto reply = make_message(*m); ++ auto reply = ceph::make_message(*m); + int pool = 1; // fixme.. do something smart! + reply->h.duration_ms = (int)(1000 * mdcache->client_lease_durations[pool]); + reply->h.seq = ++l->seq; +diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc +index 623a2e2348a19..d1cb751f54388 100644 +--- a/src/mds/MDCache.cc ++++ b/src/mds/MDCache.cc +@@ -10720,7 +10720,7 @@ void MDCache::handle_discover(const cref_t &dis) + + + CInode *cur = 0; +- auto reply = make_message(*dis); ++ auto reply = ceph::make_message(*dis); + + snapid_t snapid = dis->get_snapid(); + +diff --git a/src/mds/Server.cc b/src/mds/Server.cc +index ea60c5030dfc0..f406678d66b96 100644 +--- a/src/mds/Server.cc ++++ b/src/mds/Server.cc +@@ -154,7 +154,7 @@ class Batch_Getattr_Lookup : public BatchOp { + } + } + batch_reqs.clear(); +- server->reply_client_request(mdr, make_message(*mdr->client_request, r)); ++ server->reply_client_request(mdr, ceph::make_message(*mdr->client_request, r)); + } + void print(std::ostream& o) const override { + o << "[batch front=" << *mdr << "]"; +@@ -2167,7 +2167,7 @@ void Server::respond_to_request(const MDRequestRef& mdr, int r) + dout(20) << __func__ << ": batch head " << *mdr << dendl; + mdr->release_batch_op()->respond(r); + } else { +- reply_client_request(mdr, make_message(*mdr->client_request, r)); ++ reply_client_request(mdr, ceph::make_message(*mdr->client_request, r)); + } + } else if (mdr->internal_op > -1) { + dout(10) << __func__ << ": completing with result " << cpp_strerror(r) << " on internal " << *mdr << dendl; +@@ -2315,7 +2315,7 @@ void Server::early_reply(const MDRequestRef& mdr, CInode *tracei, CDentry *trace + } + + +- auto reply = make_message(*req, 0); ++ auto reply = ceph::make_message(*req, 0); + reply->set_unsafe(); + + // mark xlocks "done", indicating that we are exposing uncommitted changes. +@@ -2657,7 +2657,7 @@ void Server::handle_client_request(const cref_t &req) + req->get_op() != CEPH_MDS_OP_OPEN && + req->get_op() != CEPH_MDS_OP_CREATE)) { + dout(5) << "already completed " << req->get_reqid() << dendl; +- auto reply = make_message(*req, 0); ++ auto reply = ceph::make_message(*req, 0); + if (created != inodeno_t()) { + bufferlist extra; + set_reply_extra_bl(req, created, extra); diff --git a/SPECS/ceph/1004-mgr-diskprediction-disable-mypy-error.patch b/SPECS/ceph/1004-mgr-diskprediction-disable-mypy-error.patch new file mode 100644 index 0000000000..bcd1427a96 --- /dev/null +++ b/SPECS/ceph/1004-mgr-diskprediction-disable-mypy-error.patch @@ -0,0 +1,28 @@ +From 848abacfc7b9e532d362be02d7a3486f7f633f37 Mon Sep 17 00:00:00 2001 +From: John Mulligan +Date: Fri, 13 Jun 2025 18:05:50 -0400 +Subject: [PATCH] pybind/mgr: disable mypy error in diskprediction_local module + +Currently on python 3.12 mypy detects one of the variables used in the +expression as an zero-element tuple. This module is not getting a lot +of attention so I'm doing the bare minimum to stop the tests from +failing here and silencing mypy with a magic comment. + +Signed-off-by: John Mulligan +--- + src/pybind/mgr/diskprediction_local/predictor.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pybind/mgr/diskprediction_local/predictor.py b/src/pybind/mgr/diskprediction_local/predictor.py +index 3bbe7a4b7f232..858c52965941c 100644 +--- a/src/pybind/mgr/diskprediction_local/predictor.py ++++ b/src/pybind/mgr/diskprediction_local/predictor.py +@@ -168,7 +168,7 @@ def __preprocess(self, disk_days: Sequence[DevSmartT], manufacturer: str) -> Opt + roll_window_size = 6 + + # rolling means generator +- dataset_size = disk_days_attrs.shape[0] - roll_window_size + 1 ++ dataset_size = disk_days_attrs.shape[0] - roll_window_size + 1 # type: ignore + gen = (disk_days_attrs[i: i + roll_window_size, ...].mean(axis=0) + for i in range(dataset_size)) + means = np.vstack(gen) # type: ignore diff --git a/SPECS/ceph/2001-monitoring-ceph-mixin-jsonnet-bundler-version.patch b/SPECS/ceph/2001-monitoring-ceph-mixin-jsonnet-bundler-version.patch new file mode 100644 index 0000000000..9670067adc --- /dev/null +++ b/SPECS/ceph/2001-monitoring-ceph-mixin-jsonnet-bundler-version.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] monitoring/ceph-mixin: bump jsonnet-bundler JSONNET_VERSION + to v0.5.1 + +v0.4.0 lacks x/sys riscv64 stubs needed for `go install` on riscv64. + +Signed-off-by: Sun Yuechi +--- + monitoring/ceph-mixin/jsonnet-bundler-build.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/monitoring/ceph-mixin/jsonnet-bundler-build.sh b/monitoring/ceph-mixin/jsonnet-bundler-build.sh +index d713cffb8..a6be64288 100755 +--- a/monitoring/ceph-mixin/jsonnet-bundler-build.sh ++++ b/monitoring/ceph-mixin/jsonnet-bundler-build.sh +@@ -1,6 +1,6 @@ + #!/bin/sh -ex + +-JSONNET_VERSION="v0.4.0" ++JSONNET_VERSION="v0.5.1" + OUTPUT_DIR=${1:-$(pwd)} + + git clone -b ${JSONNET_VERSION} --depth 1 https://github.com/jsonnet-bundler/jsonnet-bundler diff --git a/SPECS/ceph/2002-monitoring-ceph-mixin-bump-pylint.patch b/SPECS/ceph/2002-monitoring-ceph-mixin-bump-pylint.patch new file mode 100644 index 0000000000..b9baac852b --- /dev/null +++ b/SPECS/ceph/2002-monitoring-ceph-mixin-bump-pylint.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] monitoring/ceph-mixin: bump pylint to 2.17.7 for Python 3.11+ + +pylint 2.6.0 pulls wrapt 1.12.1, which imports inspect.formatargspec +(removed in Python 3.11), breaking `tox -e lint` at venv setup on +Python 3.13. + +2.17.7 is the last 2.x release and keeps .pylintrc usable as-is +(pylint 3.x renamed many of the checkers it references). + +Signed-off-by: Sun Yuechi +--- + monitoring/ceph-mixin/requirements-lint.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/monitoring/ceph-mixin/requirements-lint.txt b/monitoring/ceph-mixin/requirements-lint.txt +index 8c7219897..3c5b039f2 100644 +--- a/monitoring/ceph-mixin/requirements-lint.txt ++++ b/monitoring/ceph-mixin/requirements-lint.txt +@@ -11,7 +11,7 @@ dataclasses==0.6 + types-dataclasses==0.6.1 + six==1.16.0 + toml==0.10.2 +-pylint==2.6.0 ++pylint==2.17.7 + isort==5.10.0 + mypy==0.910 + mypy-extensions==0.4.3 diff --git a/SPECS/ceph/2003-cephadm-tox-py313-compat.patch b/SPECS/ceph/2003-cephadm-tox-py313-compat.patch new file mode 100644 index 0000000000..fe3e423f1e --- /dev/null +++ b/SPECS/ceph/2003-cephadm-tox-py313-compat.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] cephadm: tox.ini Python 3.13 / tarball-build compatibility + +Two fixes to src/cephadm/tox.ini that both block run-tox-cephadm on a +Python 3.13 build env consuming a release tarball. + +1) Bump pyfakefs 5.3.5 -> >= 5.7.0, < 6. + 5.3.5 (2024-02) lacks Py3.13 support; 5.7.0 (2024-08) added it. + Upper bound < 6 avoids 6.0.0 (2025-12) which dropped < py3.10 and + changed FakeFilesystem back-link semantics the cephadm tests rely + on. Upstream still pins 5.3.5 on main/squid/reef -- drop once + upstream bumps. + +2) Drop the two `git ls-files ... docker.io / quay.io | wc -l` + assertions in the flake8 env. They require a .git dir, which a + release tarball has none of, and only guard against new + container-registry refs in dev PRs -- zero value on a frozen + tarball (the in-tree comment even anticipates downstream tweaks). + Pure downstream-tarball issue, no upstream tracker. + +Signed-off-by: Sun Yuechi +--- + src/cephadm/tox.ini | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/src/cephadm/tox.ini b/src/cephadm/tox.ini +index 13104797d..9d86aecf1 100644 +--- a/src/cephadm/tox.ini ++++ b/src/cephadm/tox.ini +@@ -33,7 +33,7 @@ skip_install=true + deps = + -rzipapp-reqs.txt + pyfakefs == 4.5.6 ; python_version < "3.7" +- pyfakefs == 5.3.5 ; python_version >= "3.7" ++ pyfakefs >= 5.7.0, < 6 ; python_version >= "3.7" + mock + pytest + pyyaml +@@ -58,10 +58,6 @@ deps = + flake8-quotes + commands = + flake8 --config=tox.ini {posargs:cephadm.py cephadmlib} +- bash -c 'test $(git ls-files 'cephadm.py' 'cephadmlib/*.py' | sort -u | xargs grep "docker.io" | wc -l) == 1' +- bash -c 'test $(git ls-files 'cephadm.py' 'cephadmlib/*.py' | sort -u | xargs grep "quay.io" | wc -l) == 8' +-# Downstream distributions may choose to alter this "docker.io" number, +-# to make sure no new references to docker.io are creeping in unnoticed. + + # coverage env is intentionally left out of the envlist. It is here for developers + # to run locally to generate and review test coverage of cephadm. diff --git a/SPECS/ceph/2004-test-mds-quiesce-agent-evaluate-await-idle.patch b/SPECS/ceph/2004-test-mds-quiesce-agent-evaluate-await-idle.patch new file mode 100644 index 0000000000..e4d864050c --- /dev/null +++ b/SPECS/ceph/2004-test-mds-quiesce-agent-evaluate-await-idle.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] test/mds: actually evaluate await_idle_v in + QuiesceAgentTest::update + +The TestQuiesceAgent fixture's update() helper wraps the call to +await_idle_v() in a libc assert(). With NDEBUG defined (which openRuyi +sets via the standard cmake RelWithDebInfo flags, like Fedora and most +distros), assert() expands to ((void)0) and its argument is never +evaluated, so await_idle_v() is never called. The test then immediately +reads the default-constructed async_ack (db_version=(0:0), empty roots) +and races ahead of the agent thread, failing 4 of 7 sub-tests +(DbUpdates / QuiesceProtocol / DuplicateQuiesceRequest / +TimeoutBeforeComplete) with assertions like: + + Expected equality of these values: + 1 + ack->db_version + Which is: (0:0) + +The bug is also present in upstream main (TestQuiesceAgent.cc:195) +but happens to be masked on faster x86 because the agent thread can +sometimes still beat the test thread to setting async_ack within the +small window before the read; on slower riscv64 cores the race is lost +deterministically. Replace assert() with gtest's EXPECT_TRUE() which +always evaluates its argument and produces a proper test failure +message on timeout. + +Signed-off-by: Sun Yuechi +--- + src/test/mds/TestQuiesceAgent.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/test/mds/TestQuiesceAgent.cc b/src/test/mds/TestQuiesceAgent.cc +index aa108075f..7940d8a50 100644 +--- a/src/test/mds/TestQuiesceAgent.cc ++++ b/src/test/mds/TestQuiesceAgent.cc +@@ -192,7 +192,7 @@ class QuiesceAgentTest : public testing::Test { + if (WaitForAgent::No == wait) { + return std::nullopt; + } else { +- assert(await_idle_v(v.set_version)); ++ EXPECT_TRUE(await_idle_v(v.set_version)); + return async_ack; + } + } diff --git a/SPECS/ceph/2005-osd-osd_types-pg_fast_info_t-value-init.patch b/SPECS/ceph/2005-osd-osd_types-pg_fast_info_t-value-init.patch new file mode 100644 index 0000000000..3a4f97b528 --- /dev/null +++ b/SPECS/ceph/2005-osd-osd_types-pg_fast_info_t-value-init.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] osd/osd_types: value-initialize pg_fast_info_t test instances + +`new pg_fast_info_t` (no parens) is default-init, which leaves the POD +members in the nested anonymous struct uninitialized. check-generated.sh +runs two ceph-dencoder processes and byte-compares the output, so +whichever heap garbage each process sees makes the test fail +non-deterministically; on riscv64 it fails every run with num_object_copies +holding a 0x5555_... heap pointer value. + +Add `()` to force value-init. Upstream main fixes the same bug by changing +the API to return-by-value with emplace_back() (PR #63910), but that +touches 273 files and is not viable to backport to 20.2.1. + +Signed-off-by: Sun Yuechi +--- + src/osd/osd_types.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h +index b14686b77..29421f76a 100644 +--- a/src/osd/osd_types.h ++++ b/src/osd/osd_types.h +@@ -3335,8 +3335,8 @@ struct pg_fast_info_t { + f->close_section(); + } + static void generate_test_instances(std::list& o) { +- o.push_back(new pg_fast_info_t); +- o.push_back(new pg_fast_info_t); ++ o.push_back(new pg_fast_info_t()); ++ o.push_back(new pg_fast_info_t()); + o.back()->last_update = eversion_t(1, 2); + o.back()->last_complete = eversion_t(3, 4); + o.back()->last_user_version = version_t(5); diff --git a/SPECS/ceph/2006-isa-l-enable-on-riscv.patch b/SPECS/ceph/2006-isa-l-enable-on-riscv.patch new file mode 100644 index 0000000000..a3152b6111 --- /dev/null +++ b/SPECS/ceph/2006-isa-l-enable-on-riscv.patch @@ -0,0 +1,195 @@ +From 975121604eebb8da38d26a7a91e0f85e243f4903 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 29 Mar 2026 21:47:47 +0800 +Subject: [PATCH] isa-l: enable on RISC-V + +Signed-off-by: Sun Yuechi +--- + src/CMakeLists.txt | 2 +- + src/arch/riscv.c | 6 +++++ + src/arch/riscv.h | 1 + + src/compressor/zlib/CMakeLists.txt | 30 +++++++++++++++++++++ + src/compressor/zlib/CompressionPluginZlib.h | 6 +++++ + src/compressor/zlib/ZlibCompressor.cc | 6 ++--- + src/test/compressor/test_compression.cc | 6 ++--- + 7 files changed, 50 insertions(+), 7 deletions(-) + +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 4cc9f4a726ce5..2270a90671134 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -236,7 +236,7 @@ endif() + + # Set WITH_EC_ISA_PLUGIN early so it's available when processing common/options + # This must be set before add_subdirectory(common) is called +-if(HAVE_NASM_X64_AVX2 OR HAVE_ARMV8_SIMD) ++if(HAVE_NASM_X64_AVX2 OR HAVE_ARMV8_SIMD OR HAVE_RISCV_RVV) + set(WITH_EC_ISA_PLUGIN TRUE CACHE BOOL "") + endif() + +diff --git a/src/arch/riscv.c b/src/arch/riscv.c +index 90ab9cb872c70..5dc54acfd8690 100644 +--- a/src/arch/riscv.c ++++ b/src/arch/riscv.c +@@ -6,9 +6,14 @@ + #include + #include + ++int ceph_arch_riscv_rvv = 0; + int ceph_arch_riscv_zbc = 0; + int ceph_arch_riscv_zvbc = 0; + ++#ifndef RISCV_HWPROBE_IMA_V ++#define RISCV_HWPROBE_IMA_V (1ULL << 2) ++#endif ++ + #ifndef RISCV_HWPROBE_EXT_ZBC + #define RISCV_HWPROBE_EXT_ZBC (1ULL << 7) + #endif +@@ -30,6 +35,7 @@ void ceph_arch_riscv_probe(void) + + if (do_hwprobe(pairs, 1) == 0) { + unsigned long long ext = pairs[0].value; ++ ceph_arch_riscv_rvv = (ext & RISCV_HWPROBE_IMA_V); + ceph_arch_riscv_zbc = (ext & RISCV_HWPROBE_EXT_ZBC); + ceph_arch_riscv_zvbc = (ext & RISCV_HWPROBE_EXT_ZVBC); + } +diff --git a/src/arch/riscv.h b/src/arch/riscv.h +index 2f90cb24c1d9e..495f94018217c 100644 +--- a/src/arch/riscv.h ++++ b/src/arch/riscv.h +@@ -13,6 +13,7 @@ + extern "C" { + #endif + ++extern int ceph_arch_riscv_rvv; + extern int ceph_arch_riscv_zbc; + extern int ceph_arch_riscv_zvbc; + +diff --git a/src/compressor/zlib/CMakeLists.txt b/src/compressor/zlib/CMakeLists.txt +index 3266025464997..4bacb5b18152a 100644 +--- a/src/compressor/zlib/CMakeLists.txt ++++ b/src/compressor/zlib/CMakeLists.txt +@@ -82,6 +82,36 @@ elseif(HAVE_ARMV8_SIMD) + COMPILE_DEFINITIONS "__ASSEMBLY__" + INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/src/isa-l/igzip;${PROJECT_SOURCE_DIR}/src/isa-l/igzip/aarch64" + ) ++elseif(HAVE_RISCV_RVV) ++ set(zlib_asm_sources ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/riscv64/igzip_multibinary_riscv64.S ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/riscv64/igzip_isal_adler32_rvv.S ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/riscv64/igzip_isal_adler32_rvv128.S ++ ) ++ set(zlib_sources ++ CompressionPluginZlib.cc ++ ZlibCompressor.cc ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/hufftables_c.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_base.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_base.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/adler32_base.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/flatten_ll.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/encode_df.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_icf_body.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/igzip_inflate.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/huff_codes.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/proc_heap_base.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/igzip/riscv64/igzip_multibinary_riscv64_dispatcher.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/crc/crc_base_aliases.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/crc/crc_base.c ++ ${CMAKE_SOURCE_DIR}/src/isa-l/crc/crc64_base.c ++ ${zlib_asm_sources} ++ ) ++ set_source_files_properties(${zlib_asm_sources} PROPERTIES ++ COMPILE_DEFINITIONS "__ASSEMBLY__" ++ INCLUDE_DIRECTORIES "${PROJECT_SOURCE_DIR}/src/isa-l/igzip;${PROJECT_SOURCE_DIR}/src/isa-l/igzip/riscv64" ++ ) + else() + set(zlib_sources + CompressionPluginZlib.cc +diff --git a/src/compressor/zlib/CompressionPluginZlib.h b/src/compressor/zlib/CompressionPluginZlib.h +index 597bc02a5d9a3..155345c937e1b 100644 +--- a/src/compressor/zlib/CompressionPluginZlib.h ++++ b/src/compressor/zlib/CompressionPluginZlib.h +@@ -19,6 +19,7 @@ + #include "arch/probe.h" + #include "arch/intel.h" + #include "arch/arm.h" ++#include "arch/riscv.h" + #include "common/ceph_context.h" + #include "compressor/CompressionPlugin.h" + #include "ZlibCompressor.h" +@@ -47,6 +48,11 @@ class CompressionPluginZlib : public ceph::CompressionPlugin { + ceph_arch_probe(); + isal = (ceph_arch_aarch64_pmull && ceph_arch_neon); + } ++#elif defined(HAVE_RISCV_RVV) ++ if (cct->_conf->compressor_zlib_isal) { ++ ceph_arch_probe(); ++ isal = ceph_arch_riscv_rvv; ++ } + #endif + if (compressor == 0 || has_isal != isal) { + compressor = std::make_shared(cct, isal); +diff --git a/src/compressor/zlib/ZlibCompressor.cc b/src/compressor/zlib/ZlibCompressor.cc +index 685b7fc432010..ec2fb55e6b7cf 100644 +--- a/src/compressor/zlib/ZlibCompressor.cc ++++ b/src/compressor/zlib/ZlibCompressor.cc +@@ -70,7 +70,7 @@ ZlibCompressor::ZlibCompressor(CephContext *cct, bool isal) + : Compressor(COMP_ALG_ZLIB, "zlib"), isal_enabled(isal), cct(cct) + { + +-#if !(__x86_64__ && defined(HAVE_NASM_X64_AVX2)) || defined(__aarch64__) ++#if !((__x86_64__ && defined(HAVE_NASM_X64_AVX2)) || defined(__aarch64__) || defined(HAVE_RISCV_RVV)) + if (isal_enabled) { + derr << "WARN: ISA-L enabled (compressor_zlib_isal=true) but not supported" + << dendl; +@@ -152,7 +152,7 @@ int ZlibCompressor::zlib_compress(const bufferlist &in, bufferlist &out, std::op + return 0; + } + +-#if (__x86_64__ && defined(HAVE_NASM_X64_AVX2)) || defined(__aarch64__) ++#if (__x86_64__ && defined(HAVE_NASM_X64_AVX2)) || defined(__aarch64__) || defined(HAVE_RISCV_RVV) + int ZlibCompressor::isal_compress(const bufferlist &in, bufferlist &out, std::optional &compressor_message) + { + int ret; +@@ -217,7 +217,7 @@ int ZlibCompressor::compress(const bufferlist &in, bufferlist &out, std::optiona + if (uadk_enabled) + return uadk_accel.compress(in, out); + #endif +-#if (__x86_64__ && defined(HAVE_NASM_X64_AVX2)) || defined(__aarch64__) ++#if (__x86_64__ && defined(HAVE_NASM_X64_AVX2)) || defined(__aarch64__) || defined(HAVE_RISCV_RVV) + if (isal_enabled) + return isal_compress(in, out, compressor_message); + else +diff --git a/src/test/compressor/test_compression.cc b/src/test/compressor/test_compression.cc +index 2fb5176264c27..7bf8071e3c361 100644 +--- a/src/test/compressor/test_compression.cc ++++ b/src/test/compressor/test_compression.cc +@@ -402,7 +402,7 @@ INSTANTIATE_TEST_SUITE_P( + #ifdef HAVE_LZ4 + "lz4", + #endif +-#if defined(__x86_64__) || defined(__aarch64__) ++#if defined(__x86_64__) || defined(__aarch64__) || defined(HAVE_RISCV_RVV) + "zlib/isal", + #endif + "zlib/noisal", +@@ -412,7 +412,7 @@ INSTANTIATE_TEST_SUITE_P( + #endif + "zstd")); + +-#if defined(__x86_64__) || defined(__aarch64__) ++#if defined(__x86_64__) || defined(__aarch64__) || defined(HAVE_RISCV_RVV) + + TEST(ZlibCompressor, zlib_isal_compatibility) + { +@@ -477,7 +477,7 @@ TEST(CompressionPlugin, all) + } + } + +-#if defined(__x86_64__) || defined(__aarch64__) ++#if defined(__x86_64__) || defined(__aarch64__) || defined(HAVE_RISCV_RVV) + + TEST(ZlibCompressor, isal_compress_zlib_decompress_random) + { diff --git a/SPECS/ceph/2007-librbd-pwl-cancel-timer-before-perf-stop.patch b/SPECS/ceph/2007-librbd-pwl-cancel-timer-before-perf-stop.patch new file mode 100644 index 0000000000..9115d65e94 --- /dev/null +++ b/SPECS/ceph/2007-librbd-pwl-cancel-timer-before-perf-stop.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] librbd/cache/pwl: cancel periodic_stats timer before + perf_stop() + +AbstractWriteLog::shut_down()'s outermost lambda calls perf_stop() which +deletes m_perfcounter, but the periodic_stats timer (re-armed every 5s) +is only canceled later in ~AbstractWriteLog(). If the timer fires in +between, periodic_stats -> update_image_cache_state dereferences the +freed m_perfcounter. + +Reproduces deterministically on riscv64 (sg2044) running +TestMockCacheSSDWriteLog.compare_and_write_compare_failed, whose +write/cmp/read sequence finishes in well under 5s. Upstream main HEAD +has the same code. + +Cancel m_timer_ctx under m_timer_lock before perf_stop(), mirroring the +destructor's cleanup. + +Signed-off-by: Sun Yuechi +--- + src/librbd/cache/pwl/AbstractWriteLog.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/librbd/cache/pwl/AbstractWriteLog.cc b/src/librbd/cache/pwl/AbstractWriteLog.cc +index e407d1a5d..e37ed7f75 100644 +--- a/src/librbd/cache/pwl/AbstractWriteLog.cc ++++ b/src/librbd/cache/pwl/AbstractWriteLog.cc +@@ -649,6 +649,11 @@ void AbstractWriteLog::shut_down(Context *on_finish) { + + Context *ctx = new LambdaContext( + [this, on_finish](int r) { ++ { ++ std::lock_guard timer_locker(*m_timer_lock); ++ m_timer->cancel_event(m_timer_ctx); ++ m_timer_ctx = nullptr; ++ } + if (m_perfcounter) { + perf_stop(); + } diff --git a/SPECS/ceph/2008-cephadm-tests-pyfakefs-5.7-compat.patch b/SPECS/ceph/2008-cephadm-tests-pyfakefs-5.7-compat.patch new file mode 100644 index 0000000000..8e717b9722 --- /dev/null +++ b/SPECS/ceph/2008-cephadm-tests-pyfakefs-5.7-compat.patch @@ -0,0 +1,80 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] cephadm/tests: make tests pass under pyfakefs >= 5.7 + +Upstream pins pyfakefs to 5.3.5 in src/cephadm/tox.ini to avoid this; +after `2003-cephadm-tox-py313-compat.patch` lets us bump to a +Py3.13-capable pyfakefs (5.10.2), two latent bugs surface. + +1) fixtures.py: pyfakefs 5.7 added DAC enforcement in + FakeFile.has_permission (called from lresolve/open) without a root + bypass. The fixture relies on set_uid(0) to "become root", but + after cephadm chowns dirs to a service uid (0o700/0o770) the + fake-root process gets EACCES via the "other" perm class. + + Fix: in cephadm_fs, monkey-patch FakeFile.has_permission to return + True for uid 0 -- matches kernel DAC semantics, scoped to the + fixture, no pyfakefs modification. Drop once upstream supports + pyfakefs >= 5.7 or pyfakefs grows a native root-bypass option. + +2) test_cephadm.py: TestCheckHost::test_container_engine mocks + cephadm.find_executable, but command_check_host actually calls + find_program('lvcreate') (a separate function, not an alias). The + mock is a no-op and the test only passes when lvm2 is installed on + the host -- it isn't, on openRuyi riscv64 (the lvm2 package there + only ships device-mapper, no userspace binaries). + + Fix: add a matching find_program mock. Upstream main has the same + bug but isn't hit because their CI installs lvm2. Drop if upstream + adds the mock or unifies on find_executable. + +Signed-off-by: Sun Yuechi +--- + src/cephadm/tests/fixtures.py | 15 +++++++++++++++ + src/cephadm/tests/test_cephadm.py | 3 ++- + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/cephadm/tests/fixtures.py b/src/cephadm/tests/fixtures.py +index 50ac5c1c1..aa251fc05 100644 +--- a/src/cephadm/tests/fixtures.py ++++ b/src/cephadm/tests/fixtures.py +@@ -88,6 +88,21 @@ def cephadm_fs( + srcdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + fs.add_real_directory(srcdir) + ++ # pyfakefs 5.7+ enforces st_mode permission bits in FakeFile.has_permission, ++ # unlike pyfakefs <=5.3.5 which the cephadm tests were written against. Real ++ # Linux bypasses DAC checks for uid 0, but pyfakefs has no such bypass -- ++ # after cephadm chown's a dir to a service uid (e.g. ceph 167:167), even ++ # the fake root uid set below by set_uid(0) gets EACCES on reads/writes ++ # routed through pyfakefs internals (lresolve, etc). Add a root bypass that ++ # matches Linux semantics for the duration of this fixture. ++ from pyfakefs import fake_file, helpers ++ _orig_has_permission = fake_file.FakeFile.has_permission ++ def _has_permission_root_bypass(self, permission_bits: int) -> bool: ++ if helpers.get_uid() == 0: ++ return True ++ return _orig_has_permission(self, permission_bits) ++ fake_file.FakeFile.has_permission = _has_permission_root_bypass ++ + uid = os.getuid() + gid = os.getgid() + +diff --git a/src/cephadm/tests/test_cephadm.py b/src/cephadm/tests/test_cephadm.py +index ddb98c420..62305392b 100644 +--- a/src/cephadm/tests/test_cephadm.py ++++ b/src/cephadm/tests/test_cephadm.py +@@ -2282,10 +2282,11 @@ exec /usr/bin/docker run --rm --ipc=host --stop-signal=SIGTERM --ulimit nofile=1 + + class TestCheckHost: + ++ @mock.patch('cephadm.find_program', return_value='/usr/sbin/lvcreate') + @mock.patch('cephadm.find_executable', return_value='foo') + @mock.patch('cephadm.check_time_sync', return_value=True) + @mock.patch('cephadm.logger') +- def test_container_engine(self, _logger, _find_executable, _check_time_sync): ++ def test_container_engine(self, _logger, _find_executable, _check_time_sync, _find_program): + ctx = _cephadm.CephadmContext() + + ctx.container_engine = None diff --git a/SPECS/ceph/2009-mgr-tox-skip-git-ls-files.patch b/SPECS/ceph/2009-mgr-tox-skip-git-ls-files.patch new file mode 100644 index 0000000000..bc282c3de6 --- /dev/null +++ b/SPECS/ceph/2009-mgr-tox-skip-git-ls-files.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] mgr/tox: drop `git ls-files cephadm` assertions from flake8 + env + +Same root cause as 2003-cephadm-tox-py313-compat.patch hunk 2: the +flake8 env asserts the exact count of `docker.io` / `quay.io` +references in cephadm/*.py via `git ls-files`, which fails on the +release tarball (no .git, zero matches, assertion trips). The +flake8 lint itself passes. + +These checks are only meaningful in a dev git checkout; on a frozen +tarball both counts are fixed. + +Signed-off-by: Sun Yuechi +--- + src/pybind/mgr/tox.ini | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/pybind/mgr/tox.ini b/src/pybind/mgr/tox.ini +index c2deb6272..7cff726ff 100644 +--- a/src/pybind/mgr/tox.ini ++++ b/src/pybind/mgr/tox.ini +@@ -161,8 +161,6 @@ modules = + commands = + flake8 --config=tox.ini {posargs} \ + {posargs:{[testenv:flake8]modules}} +- bash -c 'test $(git ls-files cephadm | grep ".py$" | grep -v tests | xargs grep "docker.io" | wc -l) == 3' +- bash -c 'test $(git ls-files cephadm | grep ".py$" | grep -v tests | xargs grep "quay.io" | wc -l) == 8' + + [testenv:jinjalint] + deps = diff --git a/SPECS/ceph/2010-rgw-rest-swift-error-handler-out-of-line.patch b/SPECS/ceph/2010-rgw-rest-swift-error-handler-out-of-line.patch new file mode 100644 index 0000000000..ee05d24c65 --- /dev/null +++ b/SPECS/ceph/2010-rgw-rest-swift-error-handler-out-of-line.patch @@ -0,0 +1,77 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Sun Yuechi +Date: Sun, 10 May 2026 16:06:17 +0800 +Subject: [PATCH] rgw: move RGWHandler_REST_{Bucket,Obj}_SWIFT::error_handler + bodies out-of-line + +The two `error_handler` overrides in rgw_rest_swift.h delegate to +`RGWSwiftWebsiteHandler::error_handler`, which is non-virtual and +defined in rgw_rest_swift.cc (librgw_a.a). Because the header is +included by rgw_rest.cc, the override bodies are instantiated in +librgw_common.a. Under gcc 16 -O2 the call is devirtualised into a +direct reference, turning it into a cross-archive ODR-use. + +The link command lists `librgw_a.a` before `librgw_common.a`, and GNU +ld only extracts archive members on demand: when librgw_a.a is +scanned, nothing yet references `RGWSwiftWebsiteHandler::error_handler`, +so rgw_rest_swift.cc.o is skipped and the symbol can never be resolved. + +Move the two bodies into rgw_rest_swift.cc so they sit next to the +function they call. The cross-archive ODR-use disappears and the +build no longer depends on archive scan order. No functional change. + +Signed-off-by: Sun Yuechi +--- + src/rgw/rgw_rest_swift.cc | 14 ++++++++++++++ + src/rgw/rgw_rest_swift.h | 9 ++------- + 2 files changed, 16 insertions(+), 7 deletions(-) + +diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc +index 18b96aadd..ff05c1707 100644 +--- a/src/rgw/rgw_rest_swift.cc ++++ b/src/rgw/rgw_rest_swift.cc +@@ -3256,3 +3256,17 @@ RGWHandler_REST* RGWRESTMgr_SWIFT_Info::get_handler( + const auto& auth_strategy = auth_registry.get_swift(); + return new RGWHandler_REST_SWIFT_Info(auth_strategy); + } ++ ++int RGWHandler_REST_Bucket_SWIFT::error_handler(int err_no, ++ std::string *error_content, ++ optional_yield y) ++{ ++ return website_handler->error_handler(err_no, error_content, y); ++} ++ ++int RGWHandler_REST_Obj_SWIFT::error_handler(int err_no, ++ std::string *error_content, ++ optional_yield y) ++{ ++ return website_handler->error_handler(err_no, error_content, y); ++} +diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h +index ec206a516..43ddfc5c1 100644 +--- a/src/rgw/rgw_rest_swift.h ++++ b/src/rgw/rgw_rest_swift.h +@@ -374,9 +374,7 @@ public: + using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT; + ~RGWHandler_REST_Bucket_SWIFT() override = default; + +- int error_handler(int err_no, std::string *error_content, optional_yield y) override { +- return website_handler->error_handler(err_no, error_content, y); +- } ++ int error_handler(int err_no, std::string *error_content, optional_yield y) override; + + int retarget(RGWOp* op, RGWOp** new_op, optional_yield) override { + return website_handler->retarget_bucket(op, new_op); +@@ -412,10 +410,7 @@ public: + using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT; + ~RGWHandler_REST_Obj_SWIFT() override = default; + +- int error_handler(int err_no, std::string *error_content, +- optional_yield y) override { +- return website_handler->error_handler(err_no, error_content, y); +- } ++ int error_handler(int err_no, std::string *error_content, optional_yield y) override; + + int retarget(RGWOp* op, RGWOp** new_op, optional_yield) override { + return website_handler->retarget_object(op, new_op); diff --git a/SPECS/ceph/ceph.spec b/SPECS/ceph/ceph.spec index 1e15d5a9f7..e1ef79e925 100644 --- a/SPECS/ceph/ceph.spec +++ b/SPECS/ceph/ceph.spec @@ -32,7 +32,15 @@ License: LGPL-2.1-or-later AND LGPL-3.0-only AND CC-BY-SA-3.0 AND GPL-2.0 URL: http://ceph.com/ VCS: git:https://github.com/ceph/ceph #!RemoteAsset: sha256:de779aa0141839388bb201e0a9d622b8433982e1c4d7bfc3ac6117b763972542 -Source: https://download.ceph.com/tarballs/ceph-%{version}.tar.gz +Source0: https://download.ceph.com/tarballs/ceph-%{version}.tar.gz +# Bundled isa-l v2.29 has no riscv64 support; v2.32.0 onwards ships +# riscv64 RVV sources. +#!RemoteAsset: sha256:7a194ff80d0f7e20615c497654e8a51b0184d0c79e2e265c7f555f52a26a05a4 +Source1: https://github.com/intel/isa-l/archive/refs/tags/v2.32.0.tar.gz#/isa-l-2.32.0.tar.gz +# In-place aliasing fix for the bundled isa-l v2.32.0 riscv64 RVV +# raid sources. Applied manually to src/isa-l in prep -a after the +# Source1 swap, so it is shipped as a Source rather than via patchlist. +Source2: isa-l-riscv64-rvv-raid-aliasing.patch BuildSystem: cmake BuildOption(conf): -DWITH_SYSTEM_ZSTD:BOOL=ON @@ -231,6 +239,40 @@ Requires: luarocks # Bump bundled opentelemetry-cpp cmake_minimum_required from 3.1 to 3.5 (CMake 4.x dropped <3.5 compat) 0022-src-jaegertracing-opentelemetry-cpp-CMakeLists.txt.patch +# https://github.com/ceph/ceph/commit/01dc12ad +1000-arch-add-riscv-crc32c-support.patch +# https://github.com/ceph/ceph/commit/3ccfff1a +1001-arch-riscv-fix-hwprobe.patch +# gcc 16: add missing in src/common/Formatter.h. +1002-src-common-Formatter.h-cstdint.patch +# gcc 16: fully qualify make_message<...> in src/mds/* with ceph:: to resolve ADL ambiguity. +# https://github.com/ceph/ceph/commit/ea218daf73965fdaee54693bbfcd675c031992f9 +1003-mds-qualify-make_message.patch +# mgr/diskprediction_local: backport upstream 848abacfc7b (v21.0.0) to silence mypy on numpy 2.x. +1004-mgr-diskprediction-disable-mypy-error.patch + +# riscv64: bump jsonnet-bundler JSONNET_VERSION v0.4.0 -> v0.5.1 for x/sys riscv64 stubs. +2001-monitoring-ceph-mixin-jsonnet-bundler-version.patch +# monitoring/ceph-mixin: bump pylint 2.6.0 -> 2.17.7 for Python 3.13 / wrapt compat. +2002-monitoring-ceph-mixin-bump-pylint.patch +# cephadm tox: bump pyfakefs to >=5.7,<6 and drop git ls-files refcount checks (no .git in tarball). +2003-cephadm-tox-py313-compat.patch +# unittest_mds_quiesce_agent: evaluate await_idle_v outside assert() so -DNDEBUG keeps it. +2004-test-mds-quiesce-agent-evaluate-await-idle.patch +# pg_fast_info_t generate_test_instances: value-init so check-generated.sh dump is deterministic. +2005-osd-osd_types-pg_fast_info_t-value-init.patch +# Enable ISA-L on RISC-V via HAVE_RISCV_RVV; wires bundled ISA-L v2.32 riscv64 sources. +# https://github.com/ceph/ceph/pull/68098 +2006-isa-l-enable-on-riscv.patch +# librbd PWL: cancel periodic_stats timer before perf_stop() in shut_down() to avoid UAF. +2007-librbd-pwl-cancel-timer-before-perf-stop.patch +# cephadm tests: add pyfakefs 5.7 root-bypass; fix find_executable->find_program mock site. +2008-cephadm-tests-pyfakefs-5.7-compat.patch +# mgr tox: drop two git ls-files refcount checks from flake8 env (no .git in tarball). +2009-mgr-tox-skip-git-ls-files.patch +# rgw: move SWIFT error_handler overrides out-of-line to fix gcc 16 cross-archive link error. +2010-rgw-rest-swift-error-handler-out-of-line.patch + %description Ceph is a massively scalable, open-source, distributed storage system that runs on commodity hardware and delivers object, block and file system storage. @@ -517,6 +559,17 @@ This package provides Grafana dashboards, Prometheus alerts, and SNMP MIB for monitoring Ceph clusters. %prep -a +# Replace bundled isa-l v2.29 with v2.32.0 only on riscv64: upstream v2.32 dropped +# the legacy crc32_iscsi_00.asm and other x86 source names that ceph's +# src/common/CMakeLists.txt still references on x86_64. +%ifarch riscv64 +rm -rf src/isa-l +tar -xf %{SOURCE1} -C src +mv src/isa-l-2.32.0 src/isa-l + +patch -p1 -i %{SOURCE2} +%endif + # Create two sysusers.d config files cat >ceph.sysusers.conf < +Date: Tue, 12 May 2026 19:28:27 +0800 +Subject: [PATCH] raid/riscv64: fix in-place aliasing in xor_gen and pq_gen + +sg2044: + new: xor_gen_warm: runtime = 3062177 usecs, bandwidth 50580 MB in 3.0622 sec = 16517.82 MB/s + old: xor_gen_warm: runtime = 3062535 usecs, bandwidth 31581 MB in 3.0625 sec = 10312.11 MB/s + new: pq_gen_warm: runtime = 3062480 usecs, bandwidth 16152 MB in 3.0625 sec = 5274.26 MB/s + old: pq_gen_warm: runtime = 3062583 usecs, bandwidth 14800 MB in 3.0626 sec = 4832.70 MB/s + +Signed-off-by: Sun Yuechi +--- + raid/riscv64/raid_pq_gen_rvv.S | 69 +++++++++++++++------------------ + raid/riscv64/raid_xor_gen_rvv.S | 56 +++++++++++++------------- + 2 files changed, 57 insertions(+), 68 deletions(-) + +diff --git a/src/isa-l/raid/riscv64/raid_pq_gen_rvv.S b/src/isa-l/raid/riscv64/raid_pq_gen_rvv.S +index be2a7c2..69fcc13 100644 +--- a/src/isa-l/raid/riscv64/raid_pq_gen_rvv.S ++++ b/src/isa-l/raid/riscv64/raid_pq_gen_rvv.S +@@ -33,7 +33,7 @@ + pq_gen_rvv: + srli a1, a1, 3 // blocks = len / 8 + beqz a1, ret0 // blocks <= 0 +- addi a6, a0, -3 // j = vects - 4 ++ addi a6, a0, -3 // vects - 3 + blez a6, ret1 // vects < 4 + + slli t0, a0, 3 // t0 = vects * 8 +@@ -41,36 +41,24 @@ pq_gen_rvv: + li t1, 0x8080808080808080 // bit7 + li t2, 0xfefefefefefefefe // notbit0 + li t3, 0x1d1d1d1d1d1d1d1d // gf8poly ++ li a7, 0 // byte offset ++ ++outer_strip: ++ vsetvli t4, a1, e64, m4, ta, ma ++ + ld a3, -24(t0) // src[vects-3] +- ld a4, -16(t0) // p +- ld a5, -8(t0) // q +- mv t6, a1 // save blocks +- mv t5, a4 // save p +- mv a7, a5 // save q ++ add a3, a3, a7 ++ vle64.v v0, (a3) // p ++ vmv.v.v v4, v0 // q + +-init_pq: +- vsetvli t4, t6, e64, m4, ta, ma +- vle64.v v0, (a3) +- vse64.v v0, (a4) // init p +- vse64.v v0, (a5) // init q +- sub t6, t6, t4 +- slli t4, t4, 3 +- add a3, a3, t4 +- add a4, a4, t4 +- add a5, a5, t4 +- bnez t6, init_pq ++ addi a4, t0, -32 // &array[vects-4] ++ mv a5, a6 // inner source count + +-outer_j: +- mv a4, t5 // restore p +- mv a5, a7 // restore q +- mv t6, a1 // restore blocks +- ld a0, -32(t0) // src[j] ++inner_src: ++ ld a3, 0(a4) // src[j] ++ add a3, a3, a7 ++ vle64.v v8, (a3) // s + +-inner_block: +- vsetvli t4, t6, e64, m4, ta, ma +- vle64.v v8, (a0) // s +- vle64.v v0, (a4) // p +- vle64.v v4, (a5) // q + vxor.vv v0, v0, v8 // p ^= s + vand.vx v20, v4, t1 // q & bit7 + vsll.vi v24, v4, 1 // (q << 1) +@@ -81,18 +69,23 @@ inner_block: + vand.vx v20, v20, t3 // ((q & bit7)<<1 - (q & bit7)>>7) & gf8poly + vxor.vv v4, v24, v20 // ((q << 1) & notbit0) ^ + vxor.vv v4, v4, v8 // s^ +- vse64.v v0, (a4) // p +- vse64.v v4, (a5) // q +- sub t6, t6, t4 // blocks +- slli t4, t4, 3 +- add a4, a4, t4 // p+= +- add a5, a5, t4 // q+= +- add a0, a0, t4 // s+= +- bnez t6, inner_block + +- addi a6, a6, -1 +- addi t0, t0, -8 +- bnez a6, outer_j ++ addi a4, a4, -8 ++ addi a5, a5, -1 ++ bnez a5, inner_src ++ ++ ld a3, -16(t0) // p ++ add a3, a3, a7 ++ vse64.v v0, (a3) ++ ++ ld a3, -8(t0) // q ++ add a3, a3, a7 ++ vse64.v v4, (a3) ++ ++ sub a1, a1, t4 ++ slli t5, t4, 3 ++ add a7, a7, t5 ++ bnez a1, outer_strip + + ret0: + li a0, 0 +diff --git a/src/isa-l/raid/riscv64/raid_xor_gen_rvv.S b/src/isa-l/raid/riscv64/raid_xor_gen_rvv.S +index e4754fa..dc73d00 100644 +--- a/src/isa-l/raid/riscv64/raid_xor_gen_rvv.S ++++ b/src/isa-l/raid/riscv64/raid_xor_gen_rvv.S +@@ -31,45 +31,41 @@ + .global xor_gen_rvv + .type xor_gen_rvv, %function + xor_gen_rvv: +- beqz a1, ret0 # len <= 0, return 0 +- addi t1, a0, -2 # vects - 3 ++ beqz a1, ret0 # len == 0, return 0 ++ addi t1, a0, -2 # vects - 2 + blez t1, ret1 # vects < 3, return 1 + + slli t0, a0, 3 # t0 = vects * 8 + add t0, a2, t0 # array + vects * 8 +- ld a4, 0(a2) # src[0] +- ld a3, -8(t0) # dest = array[vects - 1] +- mv t5, a3 # save dest +- mv t6, a1 # save len ++ li t2, 0 # byte offset ++ mv t6, a1 # remaining length + +-init_dest: ++outer_strip: + vsetvli t4, t6, e8, m8, ta, ma +- vle8.v v0, (a4) # load src[0] +- vse8.v v0, (a3) # dest +- sub t6, t6, t4 +- add a4, a4, t4 +- add a3, a3, t4 +- bnez t6, init_dest + +-outer_j: +- mv a3, t5 # restore dest +- mv t6, a1 # restore length +- ld a4, -16(t0) ++ ld a3, 0(a2) # array[0] ++ add a3, a3, t2 ++ vle8.v v0, (a3) + +-inner_len: +- vsetvli t4, t6, e8, m8, ta, ma +- vle8.v v0, (a4) # src[j] +- vle8.v v8, (a3) # dest +- vxor.vv v8, v8, v0 # dest ^= src[j] +- vse8.v v8, (a3) +- sub t6, t6, t4 +- add a4, a4, t4 +- add a3, a3, t4 +- bnez t6, inner_len ++ addi t3, a2, 8 # &array[1] ++ mv t5, t1 # inner source count + +- addi t1, t1, -1 +- addi t0, t0, -8 +- bnez t1, outer_j ++inner_src: ++ ld a3, 0(t3) # array[j] ++ add a3, a3, t2 ++ vle8.v v8, (a3) ++ vxor.vv v0, v0, v8 ++ addi t3, t3, 8 ++ addi t5, t5, -1 ++ bnez t5, inner_src ++ ++ ld a3, -8(t0) # dest = array[vects-1] ++ add a3, a3, t2 ++ vse8.v v0, (a3) ++ ++ sub t6, t6, t4 ++ add t2, t2, t4 ++ bnez t6, outer_strip + + ret0: + li a0, 0 +-- +2.54.0