Skip to content

[Deepin-Kernel-SIG] [linux 6.18-y] [Fromlist] Improve RISC-V strnlen() and strchr() performance#1622

Merged
opsiff merged 2 commits into
deepin-community:linux-6.18.yfrom
Avenger-285714:riscv-perf
Apr 14, 2026
Merged

[Deepin-Kernel-SIG] [linux 6.18-y] [Fromlist] Improve RISC-V strnlen() and strchr() performance#1622
opsiff merged 2 commits into
deepin-community:linux-6.18.yfrom
Avenger-285714:riscv-perf

Conversation

@Avenger-285714
Copy link
Copy Markdown
Member

@Avenger-285714 Avenger-285714 commented Apr 13, 2026

Summary by Sourcery

Add optimized RISC-V implementations of strnlen() and strchr() and integrate them into the architecture-specific string library and purgatory build.

New Features:

  • Provide an architecture-specific strnlen() implementation for RISC-V with optional Zbb-accelerated variant.
  • Provide an architecture-specific strchr() implementation for RISC-V.

Enhancements:

  • Wire the new RISC-V strnlen() and strchr() implementations into the core lib and purgatory build so they are used when KASAN is disabled.

Add an optimized strnlen() implementation for RISC-V. This version
includes a generic optimization and a Zbb-powered optimization using
the 'orc.b' instruction, derived from the strlen() implementation.

Benchmark results (QEMU TCG, rv64):
  Length | Original (MB/s) | Optimized (MB/s) | Improvement
  -------|-----------------|------------------|------------
  16 B   | 179             | 309              | +72.6%
  512 B  | 347             | 1562             | +350.1%
  4096 B | 356             | 1878             | +427.5%

Suggested-by: Qingfang Deng <dqfext@gmail.com>
Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn>
Link: https://patch.msgid.link/20260130025018.172925-7-jiangfeng@kylinos.cn
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Link: https://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git/commit/?h=for-next&id=5ba15d419fab848a3813eb56bbcad00e291fbc49
Signed-off-by: WangYuli <wangyl5933@chinaunicom.cn>
Add an assembly implementation of strchr() for RISC-V.

By eliminating stack frame management (prologue/epilogue) and optimizing
the function entries, the assembly version provides significant relative
gains for short strings where the fixed overhead of the C function is
most prominent. As string length increases, performance converges with
the generic C implementation.

Benchmark results (QEMU TCG, rv64):
  Length | Original (MB/s) | Optimized (MB/s) | Improvement
  -------|-----------------|------------------|------------
  1 B    | 21              | 22               | +4.8%
  7 B    | 113             | 121              | +7.1%
  16 B   | 195             | 202              | +3.6%
  512 B  | 376             | 389              | +3.5%
  4096 B | 394             | 393              | -0.3%

Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn>
Tested-by: Joel Stanley <joel@jms.id.au>
Link: https://patch.msgid.link/20260130025018.172925-8-jiangfeng@kylinos.cn
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Link: https://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git/commit/?h=for-next&id=adf542133960d402f63c976b00e46be4d986d4c3
Signed-off-by: WangYuli <wangyl5933@chinaunicom.cn>
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 13, 2026

Reviewer's Guide

Adds RISC-V assembly implementations of strnlen() and strchr(), wires them into the generic RISC-V string infrastructure and purgatory, and provides an optimized Zbb-based strnlen() variant when the ISA and toolchain support it.

Flow diagram for RISC-V strchr implementation

flowchart TD
  Start[Start strchr
  a0 = s, a1 = c] --> MaskChar
  MaskChar[Mask search char
  a1 = a1 & 0xff] --> Loop

  Loop[Load byte t0 = *a0] --> FoundCheck
  FoundCheck{t0 == a1?} -->|yes| ReturnPtr
  FoundCheck -->|no| NullCheck

  NullCheck{t0 == 0?} -->|yes| ReturnNull
  NullCheck -->|no| IncPtr

  IncPtr[a0 = a0 + 1] --> Loop

  ReturnPtr[Return a0] --> End
  ReturnNull[Set a0 = 0
  Return NULL] --> End

  End[End strchr]
Loading

File-Level Changes

Change Details Files
Enable use of RISC-V-specific strnlen() and strchr() implementations in both the main kernel and purgatory when KASAN is disabled.
  • Extend purgatory-y object list to include strnlen.o and strchr.o alongside existing string routines when KASAN is not enabled
  • Add explicit build rules in the RISC-V purgatory Makefile to assemble strnlen.S and strchr.S
  • Include strnlen.o and strchr.o in arch/riscv/lib/Makefile’s lib-y objects under non-KASAN builds
arch/riscv/purgatory/Makefile
arch/riscv/lib/Makefile
Declare RISC-V architecture-specific prototypes for strnlen() and strchr() so the generic code uses these implementations instead of the generic C versions.
  • Define __HAVE_ARCH_STRNLEN and declare the strnlen() prototype in the RISC-V asm string header
  • Define __HAVE_ARCH_STRCHR and declare the strchr() prototype in the RISC-V asm string header
arch/riscv/include/asm/string.h
Introduce an efficient RISC-V assembly implementation of strnlen() with an optional Zbb-accelerated path and export it for kernel-wide use, including PI aliasing.
  • Implement a simple byte-wise strnlen() loop that respects the max length bound and returns the number of bytes before NUL or count
  • Provide a Zbb-optimized strnlen_zbb variant that uses word-sized operations, bit-manipulation (orc.b, clz/ctz) and alignment handling when the RISCV_ISA_ZBB extension and toolchain support are present
  • Use __ALTERNATIVE_CFG to branch to the Zbb variant when available at runtime while keeping a generic path otherwise
  • Add SYM_FUNC_END, __pi_strnlen alias, and EXPORT_SYMBOL(strnlen) so the symbol is visible and properly annotated
arch/riscv/lib/strnlen.S
Add a lightweight RISC-V assembly implementation of strchr() and export it with a weak PI alias for use across the kernel.
  • Implement a byte-wise strchr() loop that scans for the first occurrence of a character (masked to 8 bits), terminates on match or NUL, and returns a pointer or NULL
  • Annotate the function with SYM_FUNC_START/END, provide a weak __pi_strchr alias, and EXPORT_SYMBOL(strchr)
arch/riscv/lib/strchr.S

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The new __pi_strnlen alias is defined with SYM_FUNC_ALIAS while __pi_strchr uses SYM_FUNC_ALIAS_WEAK; it would be good to align this with how other RISC-V string helpers are defined (e.g., strlen, strcmp) so the __pi_* aliases all follow a consistent strength and override behavior.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `__pi_strnlen` alias is defined with `SYM_FUNC_ALIAS` while `__pi_strchr` uses `SYM_FUNC_ALIAS_WEAK`; it would be good to align this with how other RISC-V string helpers are defined (e.g., `strlen`, `strcmp`) so the `__pi_*` aliases all follow a consistent strength and override behavior.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds RISC-V architecture-specific implementations of strnlen() (including a Zbb-accelerated variant) and strchr(), and wires them into both the normal RISC-V lib build and the kexec purgatory build so the generic C implementations can be bypassed when KASAN is not enabled.

Changes:

  • Add arch/riscv/lib/strnlen.S with an optional Zbb fast-path selected via alternatives.
  • Add arch/riscv/lib/strchr.S and expose both functions as arch-provided string routines.
  • Update RISC-V lib and purgatory Makefiles plus asm/string.h to build/use these routines when KASAN isn’t in use.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
arch/riscv/purgatory/Makefile Link strnlen.o/strchr.o into purgatory and add build rules for the new assembly sources.
arch/riscv/lib/strnlen.S New RISC-V strnlen() implementation with Zbb alternative path.
arch/riscv/lib/strchr.S New RISC-V strchr() implementation and symbol alias/export plumbing.
arch/riscv/lib/Makefile Build strnlen.o/strchr.o as part of arch/riscv/lib/ when KASAN is disabled.
arch/riscv/include/asm/string.h Advertise __HAVE_ARCH_STRNLEN / __HAVE_ARCH_STRCHR and declare the new symbols.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread arch/riscv/lib/strnlen.S
/* SPDX-License-Identifier: GPL-2.0-only */

/*
* Base on arch/riscv/lib/strlen.S
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment typo: "Base on" should be "Based on".

Suggested change
* Base on arch/riscv/lib/strlen.S
* Based on arch/riscv/lib/strlen.S

Copilot uses AI. Check for mistakes.
Comment thread arch/riscv/lib/strchr.S
ret
SYM_FUNC_END(strchr)

SYM_FUNC_ALIAS_WEAK(__pi_strchr, strchr)
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__pi_strchr is declared as a weak alias to strchr, which is inconsistent with the other RISC-V string routines in this directory (they use SYM_FUNC_ALIAS(__pi_*, *)). Unless there is a specific need for weak binding here, prefer a non-weak alias for consistency and to avoid surprising symbol resolution behavior.

Suggested change
SYM_FUNC_ALIAS_WEAK(__pi_strchr, strchr)
SYM_FUNC_ALIAS(__pi_strchr, strchr)

Copilot uses AI. Check for mistakes.
@opsiff opsiff merged commit a54af07 into deepin-community:linux-6.18.y Apr 14, 2026
14 of 16 checks passed
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: opsiff

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants