^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Common functions for in-kernel torture tests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) IBM Corporation, 2014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Paul E. McKenney <paulmck@linux.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Based on kernel/rcu/torture.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define pr_fmt(fmt) fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/sched/clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/percpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/trace_clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/torture.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "rcu/rcu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) MODULE_AUTHOR("Paul E. McKenney <paulmck@linux.ibm.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static bool disable_onoff_at_boot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) module_param(disable_onoff_at_boot, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static bool ftrace_dump_at_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) module_param(ftrace_dump_at_shutdown, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static char *torture_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int verbose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Mediate rmmod and system shutdown. Concurrent rmmod & shutdown illegal! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define FULLSTOP_DONTSTOP 0 /* Normal operation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define FULLSTOP_SHUTDOWN 1 /* System shutdown with torture running. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define FULLSTOP_RMMOD 2 /* Normal rmmod of torture. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int fullstop = FULLSTOP_RMMOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static DEFINE_MUTEX(fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #ifdef CONFIG_HOTPLUG_CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * Variables for online-offline handling. Only present if CPU hotplug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * is enabled, otherwise does nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static struct task_struct *onoff_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static long onoff_holdoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static long onoff_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static torture_ofl_func *onoff_f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static long n_offline_attempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static long n_offline_successes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static unsigned long sum_offline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static int min_offline = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static int max_offline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static long n_online_attempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static long n_online_successes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static unsigned long sum_online;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static int min_online = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int max_online;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Attempt to take a CPU offline. Return false if the CPU is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * offline or if it is not subject to CPU-hotplug operations. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * caller can detect other failures by looking at the statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) bool torture_offline(int cpu, long *n_offl_attempts, long *n_offl_successes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long *sum_offl, int *min_offl, int *max_offl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned long delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned long starttime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (!cpu_online(cpu) || !cpu_is_hotpluggable(cpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (num_online_cpus() <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return false; /* Can't offline the last CPU. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (verbose > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) pr_alert("%s" TORTURE_FLAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) "torture_onoff task: offlining %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) torture_type, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) starttime = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) (*n_offl_attempts)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ret = remove_cpu(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) s = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (!rcu_inkernel_boot_has_ended() && ret == -EBUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) // PCI probe frequently disables hotplug during boot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) (*n_offl_attempts)--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) s = " (-EBUSY forgiven during boot)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (verbose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) pr_alert("%s" TORTURE_FLAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) "torture_onoff task: offline %d failed%s: errno %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) torture_type, cpu, s, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (verbose > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pr_alert("%s" TORTURE_FLAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) "torture_onoff task: offlined %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) torture_type, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (onoff_f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) onoff_f();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) (*n_offl_successes)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) delta = jiffies - starttime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *sum_offl += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (*min_offl < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *min_offl = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) *max_offl = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (*min_offl > delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) *min_offl = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (*max_offl < delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) *max_offl = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) EXPORT_SYMBOL_GPL(torture_offline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * Attempt to bring a CPU online. Return false if the CPU is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * online or if it is not subject to CPU-hotplug operations. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * caller can detect other failures by looking at the statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) bool torture_online(int cpu, long *n_onl_attempts, long *n_onl_successes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned long *sum_onl, int *min_onl, int *max_onl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned long delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned long starttime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (cpu_online(cpu) || !cpu_is_hotpluggable(cpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (verbose > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) pr_alert("%s" TORTURE_FLAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) "torture_onoff task: onlining %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) torture_type, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) starttime = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) (*n_onl_attempts)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ret = add_cpu(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) s = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (!rcu_inkernel_boot_has_ended() && ret == -EBUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) // PCI probe frequently disables hotplug during boot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) (*n_onl_attempts)--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) s = " (-EBUSY forgiven during boot)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (verbose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) pr_alert("%s" TORTURE_FLAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) "torture_onoff task: online %d failed%s: errno %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) torture_type, cpu, s, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (verbose > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) pr_alert("%s" TORTURE_FLAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) "torture_onoff task: onlined %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) torture_type, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) (*n_onl_successes)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) delta = jiffies - starttime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *sum_onl += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (*min_onl < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *min_onl = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) *max_onl = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (*min_onl > delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *min_onl = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (*max_onl < delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *max_onl = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) EXPORT_SYMBOL_GPL(torture_online);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * Execute random CPU-hotplug operations at the interval specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * by the onoff_interval.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) torture_onoff(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int maxcpu = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) DEFINE_TORTURE_RANDOM(rand);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) VERBOSE_TOROUT_STRING("torture_onoff task started");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for_each_online_cpu(cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) maxcpu = cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) WARN_ON(maxcpu < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (!IS_MODULE(CONFIG_TORTURE_TEST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (cpu_online(cpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = add_cpu(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (ret && verbose) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) pr_alert("%s" TORTURE_FLAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) "%s: Initial online %d: errno %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) __func__, torture_type, cpu, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (maxcpu == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) VERBOSE_TOROUT_STRING("Only one CPU, so CPU-hotplug testing is disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) goto stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (onoff_holdoff > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) VERBOSE_TOROUT_STRING("torture_onoff begin holdoff");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) schedule_timeout_interruptible(onoff_holdoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) VERBOSE_TOROUT_STRING("torture_onoff end holdoff");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) while (!torture_must_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (disable_onoff_at_boot && !rcu_inkernel_boot_has_ended()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) schedule_timeout_interruptible(HZ / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) cpu = (torture_random(&rand) >> 4) % (maxcpu + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (!torture_offline(cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) &n_offline_attempts, &n_offline_successes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) &sum_offline, &min_offline, &max_offline))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) torture_online(cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) &n_online_attempts, &n_online_successes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) &sum_online, &min_online, &max_online);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) schedule_timeout_interruptible(onoff_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) stop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) torture_kthread_stopping("torture_onoff");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #endif /* #ifdef CONFIG_HOTPLUG_CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * Initiate online-offline handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int torture_onoff_init(long ooholdoff, long oointerval, torture_ofl_func *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #ifdef CONFIG_HOTPLUG_CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) onoff_holdoff = ooholdoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) onoff_interval = oointerval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) onoff_f = f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (onoff_interval <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return torture_create_kthread(torture_onoff, NULL, onoff_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #else /* #ifdef CONFIG_HOTPLUG_CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) EXPORT_SYMBOL_GPL(torture_onoff_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * Clean up after online/offline testing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void torture_onoff_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #ifdef CONFIG_HOTPLUG_CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (onoff_task == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) VERBOSE_TOROUT_STRING("Stopping torture_onoff task");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) kthread_stop(onoff_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) onoff_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #endif /* #ifdef CONFIG_HOTPLUG_CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * Print online/offline testing statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) void torture_onoff_stats(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #ifdef CONFIG_HOTPLUG_CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pr_cont("onoff: %ld/%ld:%ld/%ld %d,%d:%d,%d %lu:%lu (HZ=%d) ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) n_online_successes, n_online_attempts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) n_offline_successes, n_offline_attempts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) min_online, max_online,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) min_offline, max_offline,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) sum_online, sum_offline, HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #endif /* #ifdef CONFIG_HOTPLUG_CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) EXPORT_SYMBOL_GPL(torture_onoff_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * Were all the online/offline operations successful?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) bool torture_onoff_failures(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #ifdef CONFIG_HOTPLUG_CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return n_online_successes != n_online_attempts ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) n_offline_successes != n_offline_attempts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) #else /* #ifdef CONFIG_HOTPLUG_CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) EXPORT_SYMBOL_GPL(torture_onoff_failures);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) #define TORTURE_RANDOM_MULT 39916801 /* prime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #define TORTURE_RANDOM_ADD 479001701 /* prime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #define TORTURE_RANDOM_REFRESH 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * Crude but fast random-number generator. Uses a linear congruential
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * generator, with occasional help from cpu_clock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) torture_random(struct torture_random_state *trsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (--trsp->trs_count < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) trsp->trs_state += (unsigned long)local_clock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) trsp->trs_count = TORTURE_RANDOM_REFRESH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) trsp->trs_state = trsp->trs_state * TORTURE_RANDOM_MULT +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) TORTURE_RANDOM_ADD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return swahw32(trsp->trs_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) EXPORT_SYMBOL_GPL(torture_random);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Variables for shuffling. The idea is to ensure that each CPU stays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * idle for an extended period to test interactions with dyntick idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * as well as interactions with any per-CPU variables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct shuffle_task {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct list_head st_l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct task_struct *st_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static long shuffle_interval; /* In jiffies. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static struct task_struct *shuffler_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static cpumask_var_t shuffle_tmp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static int shuffle_idle_cpu; /* Force all torture tasks off this CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static struct list_head shuffle_task_list = LIST_HEAD_INIT(shuffle_task_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static DEFINE_MUTEX(shuffle_task_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * Register a task to be shuffled. If there is no memory, just splat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * and don't bother registering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) void torture_shuffle_task_register(struct task_struct *tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct shuffle_task *stp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (WARN_ON_ONCE(tp == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) stp = kmalloc(sizeof(*stp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (WARN_ON_ONCE(stp == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) stp->st_t = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) mutex_lock(&shuffle_task_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) list_add(&stp->st_l, &shuffle_task_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) mutex_unlock(&shuffle_task_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) EXPORT_SYMBOL_GPL(torture_shuffle_task_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * Unregister all tasks, for example, at the end of the torture run.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static void torture_shuffle_task_unregister_all(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct shuffle_task *stp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct shuffle_task *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) mutex_lock(&shuffle_task_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) list_for_each_entry_safe(stp, p, &shuffle_task_list, st_l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) list_del(&stp->st_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) kfree(stp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mutex_unlock(&shuffle_task_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* Shuffle tasks such that we allow shuffle_idle_cpu to become idle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * A special case is when shuffle_idle_cpu = -1, in which case we allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * the tasks to run on all CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static void torture_shuffle_tasks(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct shuffle_task *stp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) cpumask_setall(shuffle_tmp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) get_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* No point in shuffling if there is only one online CPU (ex: UP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (num_online_cpus() == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* Advance to the next CPU. Upon overflow, don't idle any CPUs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) shuffle_idle_cpu = cpumask_next(shuffle_idle_cpu, shuffle_tmp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (shuffle_idle_cpu >= nr_cpu_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) shuffle_idle_cpu = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) cpumask_clear_cpu(shuffle_idle_cpu, shuffle_tmp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) mutex_lock(&shuffle_task_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) list_for_each_entry(stp, &shuffle_task_list, st_l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) set_cpus_allowed_ptr(stp->st_t, shuffle_tmp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) mutex_unlock(&shuffle_task_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* Shuffle tasks across CPUs, with the intent of allowing each CPU in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * system to become idle at a time and cut off its timer ticks. This is meant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * to test the support for such tickless idle CPU in RCU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int torture_shuffle(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) VERBOSE_TOROUT_STRING("torture_shuffle task started");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) schedule_timeout_interruptible(shuffle_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) torture_shuffle_tasks();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) torture_shutdown_absorb("torture_shuffle");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) } while (!torture_must_stop());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) torture_kthread_stopping("torture_shuffle");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * Start the shuffler, with shuffint in jiffies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int torture_shuffle_init(long shuffint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) shuffle_interval = shuffint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) shuffle_idle_cpu = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (!alloc_cpumask_var(&shuffle_tmp_mask, GFP_KERNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) VERBOSE_TOROUT_ERRSTRING("Failed to alloc mask");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* Create the shuffler thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return torture_create_kthread(torture_shuffle, NULL, shuffler_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) EXPORT_SYMBOL_GPL(torture_shuffle_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * Stop the shuffling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static void torture_shuffle_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) torture_shuffle_task_unregister_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (shuffler_task) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) VERBOSE_TOROUT_STRING("Stopping torture_shuffle task");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) kthread_stop(shuffler_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) free_cpumask_var(shuffle_tmp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) shuffler_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * Variables for auto-shutdown. This allows "lights out" torture runs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * to be fully scripted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static struct task_struct *shutdown_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static ktime_t shutdown_time; /* time to system shutdown. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static void (*torture_shutdown_hook)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * Absorb kthreads into a kernel function that won't return, so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * they won't ever access module text or data again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) void torture_shutdown_absorb(const char *title)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) while (READ_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) pr_notice("torture thread %s parking due to system shutdown\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) EXPORT_SYMBOL_GPL(torture_shutdown_absorb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * Cause the torture test to shutdown the system after the test has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * run for the time specified by the shutdown_secs parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static int torture_shutdown(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ktime_t ktime_snap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) VERBOSE_TOROUT_STRING("torture_shutdown task started");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ktime_snap = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) while (ktime_before(ktime_snap, shutdown_time) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) !torture_must_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (verbose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) pr_alert("%s" TORTURE_FLAG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) "torture_shutdown task: %llu ms remaining\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) torture_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ktime_ms_delta(shutdown_time, ktime_snap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) schedule_hrtimeout(&shutdown_time, HRTIMER_MODE_ABS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ktime_snap = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (torture_must_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) torture_kthread_stopping("torture_shutdown");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* OK, shut down the system. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) VERBOSE_TOROUT_STRING("torture_shutdown task shutting down system");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) shutdown_task = NULL; /* Avoid self-kill deadlock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (torture_shutdown_hook)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) torture_shutdown_hook();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) VERBOSE_TOROUT_STRING("No torture_shutdown_hook(), skipping.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (ftrace_dump_at_shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) rcu_ftrace_dump(DUMP_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) kernel_power_off(); /* Shut down the system. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * Start up the shutdown task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) int torture_shutdown_init(int ssecs, void (*cleanup)(void))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) torture_shutdown_hook = cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (ssecs > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) shutdown_time = ktime_add(ktime_get(), ktime_set(ssecs, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return torture_create_kthread(torture_shutdown, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) shutdown_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) EXPORT_SYMBOL_GPL(torture_shutdown_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * Detect and respond to a system shutdown.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static int torture_shutdown_notify(struct notifier_block *unused1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) unsigned long unused2, void *unused3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) mutex_lock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (READ_ONCE(fullstop) == FULLSTOP_DONTSTOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) VERBOSE_TOROUT_STRING("Unscheduled system shutdown detected");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) WRITE_ONCE(fullstop, FULLSTOP_SHUTDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) pr_warn("Concurrent rmmod and shutdown illegal!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) mutex_unlock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static struct notifier_block torture_shutdown_nb = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .notifier_call = torture_shutdown_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * Shut down the shutdown task. Say what??? Heh! This can happen if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * the torture module gets an rmmod before the shutdown time arrives. ;-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static void torture_shutdown_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) unregister_reboot_notifier(&torture_shutdown_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (shutdown_task != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) VERBOSE_TOROUT_STRING("Stopping torture_shutdown task");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) kthread_stop(shutdown_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) shutdown_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * Variables for stuttering, which means to periodically pause and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * restart testing in order to catch bugs that appear when load is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * suddenly applied to or removed from the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static struct task_struct *stutter_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static int stutter_pause_test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static int stutter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int stutter_gap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * Block until the stutter interval ends. This must be called periodically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * by all running kthreads that need to be subject to stuttering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) bool stutter_wait(const char *title)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) int spt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) cond_resched_tasks_rcu_qs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) spt = READ_ONCE(stutter_pause_test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) for (; spt; spt = READ_ONCE(stutter_pause_test)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (spt == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) schedule_timeout_interruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) } else if (spt == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) while (READ_ONCE(stutter_pause_test))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) schedule_timeout_interruptible(round_jiffies_relative(HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) torture_shutdown_absorb(title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) EXPORT_SYMBOL_GPL(stutter_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * Cause the torture test to "stutter", starting and stopping all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * threads periodically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static int torture_stutter(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) int wtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) VERBOSE_TOROUT_STRING("torture_stutter task started");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!torture_must_stop() && stutter > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) wtime = stutter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (stutter > HZ + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) WRITE_ONCE(stutter_pause_test, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) wtime = stutter - HZ - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) schedule_timeout_interruptible(wtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) wtime = HZ + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) WRITE_ONCE(stutter_pause_test, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) schedule_timeout_interruptible(wtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) WRITE_ONCE(stutter_pause_test, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (!torture_must_stop())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) schedule_timeout_interruptible(stutter_gap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) torture_shutdown_absorb("torture_stutter");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) } while (!torture_must_stop());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) torture_kthread_stopping("torture_stutter");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * Initialize and kick off the torture_stutter kthread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int torture_stutter_init(const int s, const int sgap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) stutter = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) stutter_gap = sgap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return torture_create_kthread(torture_stutter, NULL, stutter_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) EXPORT_SYMBOL_GPL(torture_stutter_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * Cleanup after the torture_stutter kthread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static void torture_stutter_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (!stutter_task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) VERBOSE_TOROUT_STRING("Stopping torture_stutter task");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) kthread_stop(stutter_task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) stutter_task = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * Initialize torture module. Please note that this is -not- invoked via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * the usual module_init() mechanism, but rather by an explicit call from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * the client torture module. This call must be paired with a later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * torture_init_end().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * The runnable parameter points to a flag that controls whether or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * the test is currently runnable. If there is no such flag, pass in NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) bool torture_init_begin(char *ttype, int v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) mutex_lock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (torture_type != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) pr_alert("torture_init_begin: Refusing %s init: %s running.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) ttype, torture_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) pr_alert("torture_init_begin: One torture test at a time!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) mutex_unlock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) torture_type = ttype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) verbose = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) fullstop = FULLSTOP_DONTSTOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) EXPORT_SYMBOL_GPL(torture_init_begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * Tell the torture module that initialization is complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) void torture_init_end(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) mutex_unlock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) register_reboot_notifier(&torture_shutdown_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) EXPORT_SYMBOL_GPL(torture_init_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * Clean up torture module. Please note that this is -not- invoked via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * the usual module_exit() mechanism, but rather by an explicit call from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * the client torture module. Returns true if a race with system shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * is detected, otherwise, all kthreads started by functions in this file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * will be shut down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * This must be called before the caller starts shutting down its own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * kthreads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * Both torture_cleanup_begin() and torture_cleanup_end() must be paired,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * in order to correctly perform the cleanup. They are separated because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * threads can still need to reference the torture_type type, thus nullify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * only after completing all other relevant calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) bool torture_cleanup_begin(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) mutex_lock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (READ_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) pr_warn("Concurrent rmmod and shutdown illegal!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) mutex_unlock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) schedule_timeout_uninterruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) WRITE_ONCE(fullstop, FULLSTOP_RMMOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) mutex_unlock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) torture_shutdown_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) torture_shuffle_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) torture_stutter_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) torture_onoff_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) EXPORT_SYMBOL_GPL(torture_cleanup_begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) void torture_cleanup_end(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) mutex_lock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) torture_type = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) mutex_unlock(&fullstop_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) EXPORT_SYMBOL_GPL(torture_cleanup_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * Is it time for the current torture test to stop?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) bool torture_must_stop(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return torture_must_stop_irq() || kthread_should_stop();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) EXPORT_SYMBOL_GPL(torture_must_stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * Is it time for the current torture test to stop? This is the irq-safe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * version, hence no check for kthread_should_stop().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) bool torture_must_stop_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return READ_ONCE(fullstop) != FULLSTOP_DONTSTOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) EXPORT_SYMBOL_GPL(torture_must_stop_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * Each kthread must wait for kthread_should_stop() before returning from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * its top-level function, otherwise segfaults ensue. This function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * prints a "stopping" message and waits for kthread_should_stop(), and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * should be called from all torture kthreads immediately prior to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * returning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) void torture_kthread_stopping(char *title)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) char buf[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) snprintf(buf, sizeof(buf), "Stopping %s", title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) VERBOSE_TOROUT_STRING(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) while (!kthread_should_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) torture_shutdown_absorb(title);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) EXPORT_SYMBOL_GPL(torture_kthread_stopping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * Create a generic torture kthread that is immediately runnable. If you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * need the kthread to be stopped so that you can do something to it before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * it starts, you will need to open-code your own.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int _torture_create_kthread(int (*fn)(void *arg), void *arg, char *s, char *m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) char *f, struct task_struct **tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) VERBOSE_TOROUT_STRING(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) *tp = kthread_run(fn, arg, "%s", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (IS_ERR(*tp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ret = PTR_ERR(*tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) VERBOSE_TOROUT_ERRSTRING(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) *tp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) torture_shuffle_task_register(*tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) EXPORT_SYMBOL_GPL(_torture_create_kthread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * Stop a generic kthread, emitting a message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) void _torture_stop_kthread(char *m, struct task_struct **tp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (*tp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) VERBOSE_TOROUT_STRING(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) kthread_stop(*tp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) *tp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) EXPORT_SYMBOL_GPL(_torture_stop_kthread);