diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-02 12:17:24 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-10-02 12:17:24 -0700 |
| commit | 3f1fe48a36b0b6722dc3fd421d93512bac138e9a (patch) | |
| tree | b767d7f6e26bc64334d3f14f8422d187239dc45d /tools/testing/fault-injection/failcmd.sh | |
| download | linux-stable-3f1fe48a36b0b6722dc3fd421d93512bac138e9a.tar.gz linux-stable-3f1fe48a36b0b6722dc3fd421d93512bac138e9a.zip | |
Merge tag 'io_uring-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linuxgrafted
Pull io_uring fixes from Jens Axboe:
- Fix a task_work add use-after-free with SQPOLL.
The sqpoll thread could pop and complete the last request while
io_req_normal_work_add() was still looking at them after the mpscq
push.
Use the same approach as DEFER_TASKRUN to protect from that, holding
an RCU read lock across the add, and have exit wait for an RCU grace
period for SQPOLL rings as well.
- CQE32 ring fixes: correct the free entry check for 32b CQEs, zero the
big_cqe for aux CQEs, and only post the dummy skip CQE on CQE_MIXED
rings
- Mark the source filter table as COW when cloning bpf filters, so
registering another filter on the source doesn't modify the shared
table in place
- Initialize the task context before running the BPF loop
- Requeue zcrx multishot receives stopped by a local resource
- End a TX_TIMESTAMP multishot cmd when the CQ is full (lollipopkit)
* tag 'io_uring-7.3-20261002' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
io_uring: fix task_work add use-after-free with SQPOLL
io_uring/cmd_net: end TX_TIMESTAMP multishot when the CQ is full
io_uring/zcrx: requeue multishot receives stopped by a local resource
io_uring: initialize task context before running the BPF loop
io_uring: zero big_cqe for aux CQEs on CQE32 rings
io_uring: fix free entry check for 32b CQEs on CQE32 rings
io_uring: only post the dummy skip CQE on CQE_MIXED rings
io_uring/bpf_filter: mark source as COW when cloning filters
Diffstat (limited to 'tools/testing/fault-injection/failcmd.sh')
| -rwxr-xr-x | tools/testing/fault-injection/failcmd.sh | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/tools/testing/fault-injection/failcmd.sh b/tools/testing/fault-injection/failcmd.sh new file mode 100755 index 000000000..c4f243275 --- /dev/null +++ b/tools/testing/fault-injection/failcmd.sh @@ -0,0 +1,232 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# NAME +# failcmd.sh - run a command with injecting slab/page allocation failures +# +# SYNOPSIS +# failcmd.sh --help +# failcmd.sh [<options>] command [arguments] +# +# DESCRIPTION +# Run command with injecting slab/page allocation failures by fault +# injection. +# +# NOTE: you need to run this script as root. +# + +usage() +{ + cat >&2 <<EOF +Usage: $0 [options] command [arguments] + +OPTIONS + -p percent + --probability=percent + likelihood of failure injection, in percent. + Default value is 1 + + -t value + --times=value + specifies how many times failures may happen at most. + Default value is 1 + + --oom-kill-allocating-task=value + set /proc/sys/vm/oom_kill_allocating_task to specified value + before running the command. + Default value is 1 + + -h, --help + Display a usage message and exit + + --interval=value, --space=value, --verbose=value, --task-filter=value, + --stacktrace-depth=value, --require-start=value, --require-end=value, + --reject-start=value, --reject-end=value, --ignore-gfp-wait=value + See Documentation/fault-injection/fault-injection.rst for more + information + + failslab options: + --cache-filter=value + + fail_page_alloc options: + --ignore-gfp-highmem=value, --min-order=value + +ENVIRONMENT + FAILCMD_TYPE + The following values for FAILCMD_TYPE are recognized: + + failslab + inject slab allocation failures + fail_page_alloc + inject page allocation failures + + If FAILCMD_TYPE is not defined, then failslab is used. +EOF +} + +exit_if_not_hex() { + local value="$1" + if ! [[ $value =~ ^0x[0-9a-fA-F]+$ ]]; then + echo "Error: The provided value '$value' is not a valid hexadecimal number." >&2 + exit 1 + fi +} + +if [ $UID != 0 ]; then + echo must be run as root >&2 + exit 1 +fi + +DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3}'` + +if [ ! -d "$DEBUGFS" ]; then + echo debugfs is not mounted >&2 + exit 1 +fi + +FAILCMD_TYPE=${FAILCMD_TYPE:-failslab} +FAULTATTR=$DEBUGFS/$FAILCMD_TYPE + +if [ ! -d $FAULTATTR ]; then + echo $FAILCMD_TYPE is not available >&2 + exit 1 +fi + +LONGOPTS=probability:,interval:,times:,space:,verbose:,task-filter: +LONGOPTS=$LONGOPTS,stacktrace-depth:,require-start:,require-end: +LONGOPTS=$LONGOPTS,reject-start:,reject-end:,oom-kill-allocating-task:,help + +if [ $FAILCMD_TYPE = failslab ]; then + LONGOPTS=$LONGOPTS,ignore-gfp-wait:,cache-filter: +elif [ $FAILCMD_TYPE = fail_page_alloc ]; then + LONGOPTS=$LONGOPTS,ignore-gfp-wait:,ignore-gfp-highmem:,min-order: +fi + +TEMP=`getopt -o p:i:t:s:v:h --long $LONGOPTS -n 'failcmd.sh' -- "$@"` + +if [ $? != 0 ]; then + usage + exit 1 +fi + +eval set -- "$TEMP" + +fault_attr_default() +{ + echo N > $FAULTATTR/task-filter + echo 0 > $FAULTATTR/probability + echo 1 > $FAULTATTR/times +} + +fault_attr_default + +oom_kill_allocating_task_saved=`cat /proc/sys/vm/oom_kill_allocating_task` + +restore_values() +{ + fault_attr_default + echo $oom_kill_allocating_task_saved \ + > /proc/sys/vm/oom_kill_allocating_task +} + +# +# Default options +# +declare -i oom_kill_allocating_task=1 +declare task_filter=Y +declare -i probability=1 +declare -i times=1 + +while true; do + case "$1" in + -p|--probability) + probability=$2 + shift 2 + ;; + -i|--interval) + echo $2 > $FAULTATTR/interval + shift 2 + ;; + -t|--times) + times=$2 + shift 2 + ;; + -s|--space) + echo $2 > $FAULTATTR/space + shift 2 + ;; + -v|--verbose) + echo $2 > $FAULTATTR/verbose + shift 2 + ;; + --task-filter) + task_filter=$2 + shift 2 + ;; + --stacktrace-depth) + echo $2 > $FAULTATTR/stacktrace-depth + shift 2 + ;; + --require-start) + exit_if_not_hex "$2" + echo $2 > $FAULTATTR/require-start + shift 2 + ;; + --require-end) + exit_if_not_hex "$2" + echo $2 > $FAULTATTR/require-end + shift 2 + ;; + --reject-start) + exit_if_not_hex "$2" + echo $2 > $FAULTATTR/reject-start + shift 2 + ;; + --reject-end) + exit_if_not_hex "$2" + echo $2 > $FAULTATTR/reject-end + shift 2 + ;; + --oom-kill-allocating-task) + oom_kill_allocating_task=$2 + shift 2 + ;; + --ignore-gfp-wait) + echo $2 > $FAULTATTR/ignore-gfp-wait + shift 2 + ;; + --cache-filter) + echo $2 > $FAULTATTR/cache_filter + shift 2 + ;; + --ignore-gfp-highmem) + echo $2 > $FAULTATTR/ignore-gfp-highmem + shift 2 + ;; + --min-order) + echo $2 > $FAULTATTR/min-order + shift 2 + ;; + -h|--help) + usage + exit 0 + shift + ;; + --) + shift + break + ;; + esac +done + +[ -z "$1" ] && exit 0 + +echo $oom_kill_allocating_task > /proc/sys/vm/oom_kill_allocating_task +echo $task_filter > $FAULTATTR/task-filter +echo $probability > $FAULTATTR/probability +echo $times > $FAULTATTR/times + +trap "restore_values" SIGINT SIGTERM EXIT + +cmd="echo 1 > /proc/self/make-it-fail && exec $@" +bash -c "$cmd" |
