summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.defconf29
-rw-r--r--scripts/Makefile.modinst8
-rw-r--r--[-rwxr-xr-x]scripts/atomic/atomics.tbl0
-rwxr-xr-xscripts/bloat-o-meter3
-rwxr-xr-xscripts/bpf_doc.py2
-rwxr-xr-xscripts/checkpatch.pl38
-rw-r--r--scripts/const_structs.checkpatch1
-rwxr-xr-xscripts/decodecode12
-rw-r--r--scripts/dtc/dtc-parser.y11
-rw-r--r--scripts/dtc/libfdt/fdt.h4
-rwxr-xr-xscripts/dtc/of_unittest_expect183
-rw-r--r--scripts/dtc/version_gen.h2
-rw-r--r--scripts/gcc-plugins/Makefile2
-rw-r--r--scripts/gcc-plugins/gcc-common.h4
-rw-r--r--scripts/gdb/linux/cpus.py2
-rw-r--r--scripts/gdb/linux/mm.py222
-rw-r--r--scripts/gdb/vmlinux-gdb.py1
-rw-r--r--scripts/head-object-list.txt6
-rwxr-xr-xscripts/kconfig/merge_config.sh25
-rwxr-xr-xscripts/kernel-doc11
-rwxr-xr-xscripts/pahole-flags.sh4
-rw-r--r--scripts/spelling.txt17
-rwxr-xr-xscripts/tags.sh19
-rwxr-xr-xscripts/tracing/draw_functrace.py6
-rwxr-xr-xscripts/tracing/ftrace-bisect.sh34
25 files changed, 557 insertions, 89 deletions
diff --git a/scripts/Makefile.defconf b/scripts/Makefile.defconf
new file mode 100644
index 000000000000..ab271b2051a2
--- /dev/null
+++ b/scripts/Makefile.defconf
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0
+# Configuration heplers
+
+# Creates 'merged defconfigs'
+# ---------------------------------------------------------------------------
+# Usage:
+# $(call merge_into_defconfig,base_config,config_fragment1 config_fragment2 ...)
+#
+# Input config fragments without '.config' suffix
+define merge_into_defconfig
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \
+ -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/$(1) \
+ $(foreach config,$(2),$(srctree)/arch/$(ARCH)/configs/$(config).config)
+ +$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
+endef
+
+
+# Creates 'merged defconfigs without warning about overrides'
+# ---------------------------------------------------------------------------
+# Usage:
+# $(call merge_into_defconfig_override,base_config,config_fragment1 config_fragment2 ...)
+#
+# Input config fragments without '.config' suffix
+define merge_into_defconfig_override
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \
+ -Q -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/$(1) \
+ $(foreach config,$(2),$(srctree)/arch/$(ARCH)/configs/$(config).config)
+ +$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
+endef
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index 836391e5d209..ab0c5bd1a60f 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -14,7 +14,7 @@ modules := $(call read-file, $(MODORDER))
ifeq ($(KBUILD_EXTMOD),)
dst := $(MODLIB)/kernel
else
-INSTALL_MOD_DIR ?= extra
+INSTALL_MOD_DIR ?= updates
dst := $(MODLIB)/$(INSTALL_MOD_DIR)
endif
@@ -66,9 +66,13 @@ endif
# Don't stop modules_install even if we can't sign external modules.
#
ifeq ($(CONFIG_MODULE_SIG_ALL),y)
+ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),)
sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY)
+else
+sig-key := $(CONFIG_MODULE_SIG_KEY)
+endif
quiet_cmd_sign = SIGN $@
- cmd_sign = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(sig-key) certs/signing_key.x509 $@ \
+ cmd_sign = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) "$(sig-key)" certs/signing_key.x509 $@ \
$(if $(KBUILD_EXTMOD),|| true)
else
quiet_cmd_sign :=
diff --git a/scripts/atomic/atomics.tbl b/scripts/atomic/atomics.tbl
index fbee2f6190d9..fbee2f6190d9 100755..100644
--- a/scripts/atomic/atomics.tbl
+++ b/scripts/atomic/atomics.tbl
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
index f9553f60a14a..36303afa9dfc 100755
--- a/scripts/bloat-o-meter
+++ b/scripts/bloat-o-meter
@@ -80,8 +80,7 @@ def calc(oldfile, newfile, format):
if d<0: shrink, down = shrink+1, down-d
delta.append((d, name))
- delta.sort()
- delta.reverse()
+ delta.sort(reverse=True)
return grow, shrink, add, remove, up, down, delta, old, new, otot, ntot
def print_result(symboltype, symbolformat):
diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py
index e8d90829f23e..38d51e05c7a2 100755
--- a/scripts/bpf_doc.py
+++ b/scripts/bpf_doc.py
@@ -271,7 +271,7 @@ class HeaderParser(object):
if capture:
fn_defines_str += self.line
helper_name = capture.expand(r'bpf_\1')
- self.helper_enum_vals[helper_name] = int(capture[2])
+ self.helper_enum_vals[helper_name] = int(capture.group(2))
self.helper_enum_pos[helper_name] = i
i += 1
else:
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 78cc595b98ce..bd44d12965c9 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -823,7 +823,9 @@ our %deprecated_apis = (
"get_state_synchronize_sched" => "get_state_synchronize_rcu",
"cond_synchronize_sched" => "cond_synchronize_rcu",
"kmap" => "kmap_local_page",
+ "kunmap" => "kunmap_local",
"kmap_atomic" => "kmap_local_page",
+ "kunmap_atomic" => "kunmap_local",
);
#Create a search pattern for all these strings to speed up a loop below
@@ -3142,21 +3144,33 @@ sub process {
if ($sign_off =~ /^co-developed-by:$/i) {
if ($email eq $author) {
WARN("BAD_SIGN_OFF",
- "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
+ "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . $herecurr);
}
if (!defined $lines[$linenr]) {
WARN("BAD_SIGN_OFF",
- "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
- } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
+ "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr);
+ } elsif ($rawlines[$linenr] !~ /^signed-off-by:\s*(.*)/i) {
WARN("BAD_SIGN_OFF",
- "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
+ "Co-developed-by: must be immediately followed by Signed-off-by:\n" . $herecurr . $rawlines[$linenr] . "\n");
} elsif ($1 ne $email) {
WARN("BAD_SIGN_OFF",
- "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
+ "Co-developed-by and Signed-off-by: name/email do not match\n" . $herecurr . $rawlines[$linenr] . "\n");
+ }
+ }
+
+# check if Reported-by: is followed by a Link:
+ if ($sign_off =~ /^reported(?:|-and-tested)-by:$/i) {
+ if (!defined $lines[$linenr]) {
+ WARN("BAD_REPORTED_BY_LINK",
+ "Reported-by: should be immediately followed by Link: to the report\n" . $herecurr . $rawlines[$linenr] . "\n");
+ } elsif ($rawlines[$linenr] !~ m{^link:\s*https?://}i) {
+ WARN("BAD_REPORTED_BY_LINK",
+ "Reported-by: should be immediately followed by Link: with a URL to the report\n" . $herecurr . $rawlines[$linenr] . "\n");
}
}
}
+
# Check Fixes: styles is correct
if (!$in_header_lines &&
$line =~ /^\s*fixes:?\s*(?:commit\s*)?[0-9a-f]{5,}\b/i) {
@@ -3250,6 +3264,18 @@ sub process {
$commit_log_possible_stack_dump = 0;
}
+# Check for odd tags before a URI/URL
+ if ($in_commit_log &&
+ $line =~ /^\s*(\w+):\s*http/ && $1 ne 'Link') {
+ if ($1 =~ /^v(?:ersion)?\d+/i) {
+ WARN("COMMIT_LOG_VERSIONING",
+ "Patch version information should be after the --- line\n" . $herecurr);
+ } else {
+ WARN("COMMIT_LOG_USE_LINK",
+ "Unknown link reference '$1:', use 'Link:' instead\n" . $herecurr);
+ }
+ }
+
# Check for lines starting with a #
if ($in_commit_log && $line =~ /^#/) {
if (WARN("COMMIT_COMMENT_SYMBOL",
@@ -3725,7 +3751,7 @@ sub process {
}
# check for embedded filenames
- if ($rawline =~ /^\+.*\Q$realfile\E/) {
+ if ($rawline =~ /^\+.*\b\Q$realfile\E\b/) {
WARN("EMBEDDED_FILENAME",
"It's generally not useful to have the filename in the file\n" . $herecurr);
}
diff --git a/scripts/const_structs.checkpatch b/scripts/const_structs.checkpatch
index 1eeb7b42c5b9..dc39d938ea77 100644
--- a/scripts/const_structs.checkpatch
+++ b/scripts/const_structs.checkpatch
@@ -35,6 +35,7 @@ iwl_ops
kernel_param_ops
kgdb_arch
kgdb_io
+kobj_type
kset_uevent_ops
lock_manager_operations
machine_desc
diff --git a/scripts/decodecode b/scripts/decodecode
index b28fd2686561..8fe71c292381 100755
--- a/scripts/decodecode
+++ b/scripts/decodecode
@@ -93,6 +93,11 @@ disas() {
${CROSS_COMPILE}strip $t.o
fi
+ if [ "$ARCH" = "riscv" ]; then
+ OBJDUMPFLAGS="-M no-aliases --section=.text -D"
+ ${CROSS_COMPILE}strip $t.o
+ fi
+
if [ $pc_sub -ne 0 ]; then
if [ $PC ]; then
adj_vma=$(( $PC - $pc_sub ))
@@ -126,8 +131,13 @@ get_substr_opcode_bytes_num()
do
substr+="$opc"
+ opcode="$substr"
+ if [ "$ARCH" = "riscv" ]; then
+ opcode=$(echo $opcode | tr ' ' '\n' | tac | tr -d '\n')
+ fi
+
# return if opcode bytes do not match @opline anymore
- if ! echo $opline | grep -q "$substr";
+ if ! echo $opline | grep -q "$opcode";
then
break
fi
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index 46457d4bc0aa..bff1337ec266 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -404,9 +404,14 @@ arrayprefix:
* within the mask to one (i.e. | in the
* mask), all bits are one.
*/
- if (($2 > mask) && (($2 | mask) != -1ULL))
- ERROR(&@2, "Value out of range for"
- " %d-bit array element", $1.bits);
+ if (($2 > mask) && (($2 | mask) != -1ULL)) {
+ char *loc = srcpos_string(&@2);
+ fprintf(stderr,
+ "WARNING: %s: Value 0x%016" PRIx64
+ " truncated to 0x%0*" PRIx64 "\n",
+ loc, $2, $1.bits / 4, ($2 & mask));
+ free(loc);
+ }
}
$$.data = data_append_integer($1.data, $2, $1.bits);
diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h
index f2e68807f277..0c91aa7f67b5 100644
--- a/scripts/dtc/libfdt/fdt.h
+++ b/scripts/dtc/libfdt/fdt.h
@@ -35,14 +35,14 @@ struct fdt_reserve_entry {
struct fdt_node_header {
fdt32_t tag;
- char name[0];
+ char name[];
};
struct fdt_property {
fdt32_t tag;
fdt32_t len;
fdt32_t nameoff;
- char data[0];
+ char data[];
};
#endif /* !__ASSEMBLY */
diff --git a/scripts/dtc/of_unittest_expect b/scripts/dtc/of_unittest_expect
index 96b12d9ea606..0a535a8e9821 100755
--- a/scripts/dtc/of_unittest_expect
+++ b/scripts/dtc/of_unittest_expect
@@ -9,7 +9,7 @@
# on the console log that results from executing the Linux kernel
# devicetree unittest (drivers/of/unitest.c).
-$VUFX = "220201a";
+$VUFX = "230211a";
use strict 'refs';
use strict subs;
@@ -62,6 +62,8 @@ sub compare {
} else {
return 0;
}
+ } elsif ($type eq "all") {
+ return 1;
} elsif ($type eq "") {
if ($expect_next ne $got_next) {
return 0;
@@ -130,6 +132,7 @@ usage:
<<int>> matches: [+-]*[0-9]+
<<hex>> matches: (0x)*[0-9a-f]+
+ <<all>> matches: anything to end of line
'EXPECT \\' (begin) and 'EXPECT /' (end) lines are suppressed.
@@ -240,6 +243,8 @@ if ($#ARGV != 0) {
$pr_fmt = "### dt-test ### ";
$exp_begin = "${pr_fmt}EXPECT \\\\ : ";
$exp_end = "${pr_fmt}EXPECT / : ";
+$expnot_begin = "${pr_fmt}EXPECT_NOT \\\\ : ";
+$expnot_end = "${pr_fmt}EXPECT_NOT / : ";
$line_num = "";
@@ -250,6 +255,8 @@ while ($line = <ARGV>) {
chomp $line;
+ $suppress_line = 0;
+
$prefix = " "; ## 2 characters
@@ -274,7 +281,7 @@ while ($line = <ARGV>) {
if ($line =~ /^\s*$exp_begin/) {
$data = $line;
$data =~ s/^\s*$exp_begin//;
- push @begin, $data;
+ push @exp_begin_stack, $data;
if ($verbose) {
if ($print_line_num) {
@@ -302,21 +309,22 @@ while ($line = <ARGV>) {
$found = 0;
$no_begin = 0;
- if (@found_or_begin > 0) {
- $begin = pop @found_or_begin;
+ if (@exp_found_or_begin > 0) {
+ $begin = pop @exp_found_or_begin;
if (compare($data, $begin)) {
$found = 1;
+ $exp_found++;
}
} elsif (@begin > 0) {
- $begin = pop @begin;
+ $begin = pop @exp_begin_stack;
} else {
$no_begin = 1;
}
if ($no_begin) {
- $expect_missing_begin++;
- print "** ERROR: EXPECT end without any EXPECT begin:\n";
+ $exp_missing_begin++;
+ print "** ERROR: EXPECT end without matching EXPECT begin:\n";
print " end ---> $line\n";
} elsif (! $found) {
@@ -325,21 +333,101 @@ while ($line = <ARGV>) {
$line_num = sprintf("%4s ", $.);
}
- $expect_not_found++;
+ $exp_missing++;
printf "** %s%s$script_name WARNING - not found ---> %s\n",
$line_num, $timestamp, $data;
- } elsif (! compare($data, $begin)) {
+ } elsif (! compare($data, $begin) and ($data ne $begin)) {
- $expect_missing_end++;
+ $exp_missing_end++;
print "** ERROR: EXPECT end does not match EXPECT begin:\n";
print " begin -> $begin\n";
print " end ---> $line\n";
+ }
+
+ next LINE;
+ }
+
+
+ # ----- find EXPECT_NOT begin
+
+ if ($line =~ /^\s*$expnot_begin/) {
+ $data = $line;
+ $data =~ s/^\s*$expnot_begin//;
+ push @expnot_begin_stack, $data;
+
+ if ($verbose) {
+ if ($print_line_num) {
+ $line_num = sprintf("%4s ", $.);
+ }
+ printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line;
+ }
+
+ next LINE;
+ }
+
+
+ # ----- find EXPECT_NOT end
+
+ if ($line =~ /^\s*$expnot_end/) {
+ $data = $line;
+ $data =~ s/^\s*$expnot_end//;
+
+ if ($verbose) {
+ if ($print_line_num) {
+ $line_num = sprintf("%4s ", $.);
+ }
+ printf "%s %s%s%s\n", $prefix, $line_num, $timestamp, $line;
+ }
+
+ $found = 0;
+ $no_begin = 0;
+ if (@expnot_found_or_begin > 0) {
+ $begin = pop @expnot_found_or_begin;
+ if (compare($data, $begin)) {
+ $found = 1;
+ $expnot_found++;
+ }
+ } elsif (@expnot_begin_stack <= 0) {
+ $no_begin = 1;
+ }
+
+ if ($no_begin) {
+
+ $expnot_missing_begin++;
+ print "** ERROR: EXPECT_NOT end without matching EXPECT_NOT begin:\n";
+ print " end ---> $line\n";
+
+ }
+
+ if ($found) {
+
+ if ($print_line_num) {
+ $line_num = sprintf("%4s ", $.);
+ }
+
+ printf "** %s%s$script_name WARNING - next line matches EXPECT_NOT\n",
+ $line_num, $timestamp;
+ printf "** %s%s%s\n", $line_num, $timestamp, $line;
+
} else {
- $expect_found++;
+ $expnot_missing++;
+
+ }
+
+ if (@expnot_begin_stack > 0) {
+ $begin = pop @expnot_begin_stack;
+
+ if (! compare($data, $begin) and ($data ne $begin)) {
+
+ $expnot_missing_end++;
+ print "** ERROR: EXPECT_NOT end does not match EXPECT_NOT begin:\n";
+ print " begin -> $begin\n";
+ print " end ---> $line\n";
+ }
}
next LINE;
@@ -357,7 +445,30 @@ while ($line = <ARGV>) {
}
$found = 0;
- foreach $begin (@begin) {
+ foreach $begin (@exp_begin_stack) {
+ if (compare($begin, $line)) {
+ $found = 1;
+ last;
+ }
+ }
+
+ if ($found) {
+ $begin = shift @exp_begin_stack;
+ while (! compare($begin, $line)) {
+ push @exp_found_or_begin, $begin;
+ $begin = shift @exp_begin_stack;
+ }
+ push @exp_found_or_begin, $line;
+
+ if ($hide_expect) {
+ $suppress_line = 1;
+ }
+ $prefix = "ok"; # 2 characters
+ }
+
+
+ $found = 0;
+ foreach $begin (@expnot_begin_stack) {
if (compare($begin, $line)) {
$found = 1;
last;
@@ -367,19 +478,22 @@ while ($line = <ARGV>) {
if ($found) {
$begin = shift @begin;
while (! compare($begin, $line)) {
- push @found_or_begin, $begin;
+ push @expnot_found_or_begin, $begin;
$begin = shift @begin;
}
- push @found_or_begin, $line;
+ push @expnot_found_or_begin, $line;
if ($hide_expect) {
$suppress_line = 1;
- next LINE;
}
- $prefix = "ok"; # 2 characters
+ $prefix = "**"; # 2 characters
}
+ if ($suppress_line) {
+ next LINE;
+ }
+
if ($print_line_num) {
$line_num = sprintf("%4s ", $.);
}
@@ -391,18 +505,37 @@ if (! $no_expect_stats) {
print "\n";
print "** EXPECT statistics:\n";
print "**\n";
- printf "** EXPECT found : %4i\n", $expect_found;
- printf "** EXPECT not found : %4i\n", $expect_not_found;
- printf "** missing EXPECT begin : %4i\n", $expect_missing_begin;
- printf "** missing EXPECT end : %4i\n", $expect_missing_end;
- printf "** unittest FAIL : %4i\n", $unittest_fail;
- printf "** internal error : %4i\n", $internal_err;
+ printf "** non-zero values expected:\n";
+ print "**\n";
+ printf "** EXPECT found : %4i\n", $exp_found;
+ printf "** EXPECT_NOT not found : %4i\n", $expnot_missing;
+ print "**\n";
+ printf "** zero values expected:\n";
+ print "**\n";
+ printf "** EXPECT not found : %4i\n", $exp_missing;
+ printf "** missing EXPECT begin : %4i\n", $exp_missing_begin;
+ printf "** missing EXPECT end : %4i\n", $exp_missing_end;
+ print "**\n";
+ printf "** EXPECT_NOT found : %4i\n", $expnot_found;
+ printf "** missing EXPECT_NOT begin : %4i\n", $expnot_missing_begin;
+ printf "** missing EXPECT_NOT end : %4i\n", $expnot_missing_end;
+ print "**\n";
+ printf "** unittest FAIL : %4i\n", $unittest_fail;
+ printf "** internal error : %4i\n", $internal_err;
+}
+
+if (@exp_begin_stack) {
+ print "** ERROR: EXPECT begin without matching EXPECT end:\n";
+ print " This list may be misleading.\n";
+ foreach $begin (@exp_begin_stack) {
+ print " begin ---> $begin\n";
+ }
}
-if (@begin) {
- print "** ERROR: EXPECT begin without any EXPECT end:\n";
+if (@expnot_begin_stack) {
+ print "** ERROR: EXPECT_NOT begin without matching EXPECT_NOT end:\n";
print " This list may be misleading.\n";
- foreach $begin (@begin) {
+ foreach $begin (@expnot_begin_stack) {
print " begin ---> $begin\n";
}
}
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 0f303087b043..99614ec1a289 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.6.1-g55778a03"
+#define DTC_VERSION "DTC 1.6.1-gabbd523b"
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index b34d11e22636..320afd3cf8e8 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -29,7 +29,7 @@ GCC_PLUGINS_DIR = $(shell $(CC) -print-file-name=plugin)
plugin_cxxflags = -Wp,-MMD,$(depfile) $(KBUILD_HOSTCXXFLAGS) -fPIC \
-include $(srctree)/include/linux/compiler-version.h \
-DPLUGIN_VERSION=$(call stringify,$(KERNELVERSION)) \
- -I $(GCC_PLUGINS_DIR)/include -I $(obj) -std=gnu++11 \
+ -I $(GCC_PLUGINS_DIR)/include -I $(obj) \
-fno-rtti -fno-exceptions -fasynchronous-unwind-tables \
-ggdb -Wno-narrowing -Wno-unused-variable \
-Wno-format-diag
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
index 9a1895747b15..84c730da36dd 100644
--- a/scripts/gcc-plugins/gcc-common.h
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -71,7 +71,9 @@
#include "varasm.h"
#include "stor-layout.h"
#include "internal-fn.h"
+#include "gimple.h"
#include "gimple-expr.h"
+#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "context.h"
#include "tree-ssa-alias.h"
@@ -85,10 +87,8 @@
#include "tree-eh.h"
#include "stmt.h"
#include "gimplify.h"
-#include "gimple.h"
#include "tree-phinodes.h"
#include "tree-cfg.h"
-#include "gimple-iterator.h"
#include "gimple-ssa.h"
#include "ssa-iterators.h"
diff --git a/scripts/gdb/linux/cpus.py b/scripts/gdb/linux/cpus.py
index 15fc4626d236..9ee99f9fae8d 100644
--- a/scripts/gdb/linux/cpus.py
+++ b/scripts/gdb/linux/cpus.py
@@ -163,7 +163,7 @@ def get_current_task(cpu):
task_ptr_type = task_type.get_type().pointer()
if utils.is_target_arch("x86"):
- var_ptr = gdb.parse_and_eval("&current_task")
+ var_ptr = gdb.parse_and_eval("&pcpu_hot.current_task")
return per_cpu(var_ptr, cpu).dereference()
elif utils.is_target_arch("aarch64"):
current_task_addr = gdb.parse_and_eval("$SP_EL0")
diff --git a/scripts/gdb/linux/mm.py b/scripts/gdb/linux/mm.py
new file mode 100644
index 000000000000..30d837f3dfae
--- /dev/null
+++ b/scripts/gdb/linux/mm.py
@@ -0,0 +1,222 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# routines to introspect page table
+#
+# Authors:
+# Dmitrii Bundin <dmitrii.bundin.a@gmail.com>
+#
+
+import gdb
+
+from linux import utils
+
+PHYSICAL_ADDRESS_MASK = gdb.parse_and_eval('0xfffffffffffff')
+
+
+def page_mask(level=1):
+ # 4KB
+ if level == 1:
+ return gdb.parse_and_eval('(u64) ~0xfff')
+ # 2MB
+ elif level == 2:
+ return gdb.parse_and_eval('(u64) ~0x1fffff')
+ # 1GB
+ elif level == 3:
+ return gdb.parse_and_eval('(u64) ~0x3fffffff')
+ else:
+ raise Exception(f'Unknown page level: {level}')
+
+
+#page_offset_base in case CONFIG_DYNAMIC_MEMORY_LAYOUT is disabled
+POB_NO_DYNAMIC_MEM_LAYOUT = '0xffff888000000000'
+def _page_offset_base():
+ pob_symbol = gdb.lookup_global_symbol('page_offset_base')
+ pob = pob_symbol.name if pob_symbol else POB_NO_DYNAMIC_MEM_LAYOUT
+ return gdb.parse_and_eval(pob)
+
+
+def is_bit_defined_tupled(data, offset):
+ return offset, bool(data >> offset & 1)
+
+def content_tupled(data, bit_start, bit_end):
+ return (bit_start, bit_end), data >> bit_start & ((1 << (1 + bit_end - bit_start)) - 1)
+
+def entry_va(level, phys_addr, translating_va):
+ def start_bit(level):
+ if level == 5:
+ return 48
+ elif level == 4:
+ return 39
+ elif level == 3:
+ return 30
+ elif level == 2:
+ return 21
+ elif level == 1:
+ return 12
+ else:
+ raise Exception(f'Unknown level {level}')
+
+ entry_offset = ((translating_va >> start_bit(level)) & 511) * 8
+ entry_va = _page_offset_base() + phys_addr + entry_offset
+ return entry_va
+
+class Cr3():
+ def __init__(self, cr3, page_levels):
+ self.cr3 = cr3
+ self.page_levels = page_levels
+ self.page_level_write_through = is_bit_defined_tupled(cr3, 3)
+ self.page_level_cache_disabled = is_bit_defined_tupled(cr3, 4)
+ self.next_entry_physical_address = cr3 & PHYSICAL_ADDRESS_MASK & page_mask()
+
+ def next_entry(self, va):
+ next_level = self.page_levels
+ return PageHierarchyEntry(entry_va(next_level, self.next_entry_physical_address, va), next_level)
+
+ def mk_string(self):
+ return f"""\
+cr3:
+ {'cr3 binary data': <30} {hex(self.cr3)}
+ {'next entry physical address': <30} {hex(self.next_entry_physical_address)}
+ ---
+ {'bit' : <4} {self.page_level_write_through[0]: <10} {'page level write through': <30} {self.page_level_write_through[1]}
+ {'bit' : <4} {self.page_level_cache_disabled[0]: <10} {'page level cache disabled': <30} {self.page_level_cache_disabled[1]}
+"""
+
+
+class PageHierarchyEntry():
+ def __init__(self, address, level):
+ data = int.from_bytes(
+ memoryview(gdb.selected_inferior().read_memory(address, 8)),
+ "little"
+ )
+ if level == 1:
+ self.is_page = True
+ self.entry_present = is_bit_defined_tupled(data, 0)
+ self.read_write = is_bit_defined_tupled(data, 1)
+ self.user_access_allowed = is_bit_defined_tupled(data, 2)
+ self.page_level_write_through = is_bit_defined_tupled(data, 3)
+ self.page_level_cache_disabled = is_bit_defined_tupled(data, 4)
+ self.entry_was_accessed = is_bit_defined_tupled(data, 5)
+ self.dirty = is_bit_defined_tupled(data, 6)
+ self.pat = is_bit_defined_tupled(data, 7)
+ self.global_translation = is_bit_defined_tupled(data, 8)
+ self.page_physical_address = data & PHYSICAL_ADDRESS_MASK & page_mask(level)
+ self.next_entry_physical_address = None
+ self.hlat_restart_with_ordinary = is_bit_defined_tupled(data, 11)
+ self.protection_key = content_tupled(data, 59, 62)
+ self.executed_disable = is_bit_defined_tupled(data, 63)
+ else:
+ page_size = is_bit_defined_tupled(data, 7)
+ page_size_bit = page_size[1]
+ self.is_page = page_size_bit
+ self.entry_present = is_bit_defined_tupled(data, 0)
+ self.read_write = is_bit_defined_tupled(data, 1)
+ self.user_access_allowed = is_bit_defined_tupled(data, 2)
+ self.page_level_write_through = is_bit_defined_tupled(data, 3)
+ self.page_level_cache_disabled = is_bit_defined_tupled(data, 4)
+ self.entry_was_accessed = is_bit_defined_tupled(data, 5)
+ self.page_size = page_size
+ self.dirty = is_bit_defined_tupled(
+ data, 6) if page_size_bit else None
+ self.global_translation = is_bit_defined_tupled(
+ data, 8) if page_size_bit else None
+ self.pat = is_bit_defined_tupled(
+ data, 12) if page_size_bit else None
+ self.page_physical_address = data & PHYSICAL_ADDRESS_MASK & page_mask(level) if page_size_bit else None
+ self.next_entry_physical_address = None if page_size_bit else data & PHYSICAL_ADDRESS_MASK & page_mask()
+ self.hlat_restart_with_ordinary = is_bit_defined_tupled(data, 11)
+ self.protection_key = content_tupled(data, 59, 62) if page_size_bit else None
+ self.executed_disable = is_bit_defined_tupled(data, 63)
+ self.address = address
+ self.page_entry_binary_data = data
+ self.page_hierarchy_level = level
+
+ def next_entry(self, va):
+ if self.is_page or not self.entry_present[1]:
+ return None
+
+ next_level = self.page_hierarchy_level - 1
+ return PageHierarchyEntry(entry_va(next_level, self.next_entry_physical_address, va), next_level)
+
+
+ def mk_string(self):
+ if not self.entry_present[1]:
+ return f"""\
+level {self.page_hierarchy_level}:
+ {'entry address': <30} {hex(self.address)}
+ {'page entry binary data': <30} {hex(self.page_entry_binary_data)}
+ ---
+ PAGE ENTRY IS NOT PRESENT!
+"""
+ elif self.is_page:
+ def page_size_line(ps_bit, ps, level):
+ return "" if level == 1 else f"{'bit': <3} {ps_bit: <5} {'page size': <30} {ps}"
+
+ return f"""\
+level {self.page_hierarchy_level}:
+ {'entry address': <30} {hex(self.address)}
+ {'page entry binary data': <30} {hex(self.page_entry_binary_data)}
+ {'page size': <30} {'1GB' if self.page_hierarchy_level == 3 else '2MB' if self.page_hierarchy_level == 2 else '4KB' if self.page_hierarchy_level == 1 else 'Unknown page size for level:' + self.page_hierarchy_level}
+ {'page physical address': <30} {hex(self.page_physical_address)}
+ ---
+ {'bit': <4} {self.entry_present[0]: <10} {'entry present': <30} {self.entry_present[1]}
+ {'bit': <4} {self.read_write[0]: <10} {'read/write access allowed': <30} {self.read_write[1]}
+ {'bit': <4} {self.user_access_allowed[0]: <10} {'user access allowed': <30} {self.user_access_allowed[1]}
+ {'bit': <4} {self.page_level_write_through[0]: <10} {'page level write through': <30} {self.page_level_write_through[1]}
+ {'bit': <4} {self.page_level_cache_disabled[0]: <10} {'page level cache disabled': <30} {self.page_level_cache_disabled[1]}
+ {'bit': <4} {self.entry_was_accessed[0]: <10} {'entry has been accessed': <30} {self.entry_was_accessed[1]}
+ {"" if self.page_hierarchy_level == 1 else f"{'bit': <4} {self.page_size[0]: <10} {'page size': <30} {self.page_size[1]}"}
+ {'bit': <4} {self.dirty[0]: <10} {'page dirty': <30} {self.dirty[1]}
+ {'bit': <4} {self.global_translation[0]: <10} {'global translation': <30} {self.global_translation[1]}
+ {'bit': <4} {self.hlat_restart_with_ordinary[0]: <10} {'restart to ordinary': <30} {self.hlat_restart_with_ordinary[1]}
+ {'bit': <4} {self.pat[0]: <10} {'pat': <30} {self.pat[1]}
+ {'bits': <4} {str(self.protection_key[0]): <10} {'protection key': <30} {self.protection_key[1]}
+ {'bit': <4} {self.executed_disable[0]: <10} {'execute disable': <30} {self.executed_disable[1]}
+"""
+ else:
+ return f"""\
+level {self.page_hierarchy_level}:
+ {'entry address': <30} {hex(self.address)}
+ {'page entry binary data': <30} {hex(self.page_entry_binary_data)}
+ {'next entry physical address': <30} {hex(self.next_entry_physical_address)}
+ ---
+ {'bit': <4} {self.entry_present[0]: <10} {'entry present': <30} {self.entry_present[1]}
+ {'bit': <4} {self.read_write[0]: <10} {'read/write access allowed': <30} {self.read_write[1]}
+ {'bit': <4} {self.user_access_allowed[0]: <10} {'user access allowed': <30} {self.user_access_allowed[1]}
+ {'bit': <4} {self.page_level_write_through[0]: <10} {'page level write through': <30} {self.page_level_write_through[1]}
+ {'bit': <4} {self.page_level_cache_disabled[0]: <10} {'page level cache disabled': <30} {self.page_level_cache_disabled[1]}
+ {'bit': <4} {self.entry_was_accessed[0]: <10} {'entry has been accessed': <30} {self.entry_was_accessed[1]}
+ {'bit': <4} {self.page_size[0]: <10} {'page size': <30} {self.page_size[1]}
+ {'bit': <4} {self.hlat_restart_with_ordinary[0]: <10} {'restart to ordinary': <30} {self.hlat_restart_with_ordinary[1]}
+ {'bit': <4} {self.executed_disable[0]: <10} {'execute disable': <30} {self.executed_disable[1]}
+"""
+
+
+class TranslateVM(gdb.Command):
+ """Prints the entire paging structure used to translate a given virtual address.
+
+Having an address space of the currently executed process translates the virtual address
+and prints detailed information of all paging structure levels used for the transaltion.
+Currently supported arch: x86"""
+
+ def __init__(self):
+ super(TranslateVM, self).__init__('translate-vm', gdb.COMMAND_USER)
+
+ def invoke(self, arg, from_tty):
+ if utils.is_target_arch("x86"):
+ vm_address = gdb.parse_and_eval(f'{arg}')
+ cr3_data = gdb.parse_and_eval('$cr3')
+ cr4 = gdb.parse_and_eval('$cr4')
+ page_levels = 5 if cr4 & (1 << 12) else 4
+ page_entry = Cr3(cr3_data, page_levels)
+ while page_entry:
+ gdb.write(page_entry.mk_string())
+ page_entry = page_entry.next_entry(vm_address)
+ else:
+ gdb.GdbError("Virtual address translation is not"
+ "supported for this arch")
+
+
+TranslateVM()
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
index 3e8d3669f0ce..3a5b44cd6bfe 100644
--- a/scripts/gdb/vmlinux-gdb.py
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -37,3 +37,4 @@ else:
import linux.clk
import linux.genpd
import linux.device
+ import linux.mm
diff --git a/scripts/head-object-list.txt b/scripts/head-object-list.txt
index b074134cfac2..b2a0e21ea8d7 100644
--- a/scripts/head-object-list.txt
+++ b/scripts/head-object-list.txt
@@ -42,10 +42,4 @@ arch/s390/kernel/head64.o
arch/sh/kernel/head_32.o
arch/sparc/kernel/head_32.o
arch/sparc/kernel/head_64.o
-arch/x86/kernel/head_32.o
-arch/x86/kernel/head_64.o
-arch/x86/kernel/head32.o
-arch/x86/kernel/head64.o
-arch/x86/kernel/ebda.o
-arch/x86/kernel/platform-quirks.o
arch/xtensa/kernel/head.o
diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh
index e5b46980c22a..32620de473ad 100755
--- a/scripts/kconfig/merge_config.sh
+++ b/scripts/kconfig/merge_config.sh
@@ -29,6 +29,7 @@ usage() {
echo " -y make builtin have precedence over modules"
echo " -O dir to put generated output files. Consider setting \$KCONFIG_CONFIG instead."
echo " -s strict mode. Fail if the fragment redefines any value."
+ echo " -Q disable warning messages for overridden options."
echo
echo "Used prefix: '$CONFIG_PREFIX'. You can redefine it with \$CONFIG_ environment variable."
}
@@ -40,6 +41,7 @@ BUILTIN=false
OUTPUT=.
STRICT=false
CONFIG_PREFIX=${CONFIG_-CONFIG_}
+WARNOVERRIDE=echo
while true; do
case $1 in
@@ -82,6 +84,11 @@ while true; do
shift
continue
;;
+ "-Q")
+ WARNOVERRIDE=true
+ shift
+ continue
+ ;;
*)
break
;;
@@ -138,21 +145,21 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do
NEW_VAL=$(grep -w $CFG $MERGE_FILE)
BUILTIN_FLAG=false
if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then
- echo Previous value: $PREV_VAL
- echo New value: $NEW_VAL
- echo -y passed, will not demote y to m
- echo
+ ${WARNOVVERIDE} Previous value: $PREV_VAL
+ ${WARNOVERRIDE} New value: $NEW_VAL
+ ${WARNOVERRIDE} -y passed, will not demote y to m
+ ${WARNOVERRIDE}
BUILTIN_FLAG=true
elif [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then
- echo Value of $CFG is redefined by fragment $ORIG_MERGE_FILE:
- echo Previous value: $PREV_VAL
- echo New value: $NEW_VAL
- echo
+ ${WARNOVERRIDE} Value of $CFG is redefined by fragment $ORIG_MERGE_FILE:
+ ${WARNOVERRIDE} Previous value: $PREV_VAL
+ ${WARNOVERRIDE} New value: $NEW_VAL
+ ${WARNOVERRIDE}
if [ "$STRICT" = "true" ]; then
STRICT_MODE_VIOLATED=true
fi
elif [ "$WARNREDUN" = "true" ]; then
- echo Value of $CFG is redundant by fragment $ORIG_MERGE_FILE:
+ ${WARNOVERRIDE} Value of $CFG is redundant by fragment $ORIG_MERGE_FILE:
fi
if [ "$BUILTIN_FLAG" = "false" ]; then
sed -i "/$CFG[ =]/d" $TMP_FILE
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 8ad0a7d68d9a..2486689ffc7b 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -2079,17 +2079,6 @@ sub process_name($$) {
sub process_body($$) {
my $file = shift;
- # Until all named variable macro parameters are
- # documented using the bare name (`x`) rather than with
- # dots (`x...`), strip the dots:
- if ($section =~ /\w\.\.\.$/) {
- $section =~ s/\.\.\.$//;
-
- if ($verbose) {
- emit_warning("${file}:$.", "Variable macro arguments should be documented without dots\n");
- }
- }
-
if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) {
dump_section($file, $section, $contents);
$section = $section_default;
diff --git a/scripts/pahole-flags.sh b/scripts/pahole-flags.sh
index 0d99ef17e4a5..1f1f1d397c39 100755
--- a/scripts/pahole-flags.sh
+++ b/scripts/pahole-flags.sh
@@ -19,5 +19,9 @@ fi
if [ "${pahole_ver}" -ge "122" ]; then
extra_paholeopt="${extra_paholeopt} -j"
fi
+if [ "${pahole_ver}" -ge "124" ]; then
+ # see PAHOLE_HAS_LANG_EXCLUDE
+ extra_paholeopt="${extra_paholeopt} --lang_exclude=rust"
+fi
echo ${extra_paholeopt}
diff --git a/scripts/spelling.txt b/scripts/spelling.txt
index ded8bcfc0247..f8bd6178d17b 100644
--- a/scripts/spelling.txt
+++ b/scripts/spelling.txt
@@ -65,6 +65,7 @@ acumulative||accumulative
acumulator||accumulator
acutally||actually
adapater||adapter
+adderted||asserted
addional||additional
additionaly||additionally
additonal||additional
@@ -122,6 +123,7 @@ alue||value
ambigious||ambiguous
ambigous||ambiguous
amoung||among
+amount of times||number of times
amout||amount
amplifer||amplifier
amplifyer||amplifier
@@ -287,6 +289,7 @@ capapbilities||capabilities
caputure||capture
carefuly||carefully
cariage||carriage
+casued||caused
catagory||category
cehck||check
challange||challenge
@@ -370,6 +373,7 @@ conbination||combination
conditionaly||conditionally
conditon||condition
condtion||condition
+condtional||conditional
conected||connected
conector||connector
configration||configuration
@@ -423,6 +427,7 @@ cound||could
couter||counter
coutner||counter
cryptocraphic||cryptographic
+cummulative||cumulative
cunter||counter
curently||currently
cylic||cyclic
@@ -625,8 +630,10 @@ exeuction||execution
existance||existence
existant||existent
exixt||exist
+exsits||exists
exlcude||exclude
exlcusive||exclusive
+exlusive||exclusive
exmaple||example
expecially||especially
experies||expires
@@ -664,11 +671,13 @@ feauture||feature
feautures||features
fetaure||feature
fetaures||features
+fetcing||fetching
fileystem||filesystem
fimrware||firmware
fimware||firmware
firmare||firmware
firmaware||firmware
+firtly||firstly
firware||firmware
firwmare||firmware
finanize||finalize
@@ -838,6 +847,7 @@ integrety||integrity
integrey||integrity
intendet||intended
intented||intended
+interal||internal
interanl||internal
interchangable||interchangeable
interferring||interfering
@@ -1023,6 +1033,7 @@ negotation||negotiation
nerver||never
nescessary||necessary
nessessary||necessary
+none existent||non-existent
noticable||noticeable
notication||notification
notications||notifications
@@ -1044,6 +1055,7 @@ occured||occurred
occurence||occurrence
occure||occurred
occuring||occurring
+ocurrence||occurrence
offser||offset
offet||offset
offlaod||offload
@@ -1055,6 +1067,7 @@ omitt||omit
ommiting||omitting
ommitted||omitted
onself||oneself
+onthe||on the
ony||only
openning||opening
operatione||operation
@@ -1121,6 +1134,7 @@ perfomring||performing
periperal||peripheral
peripherial||peripheral
permissons||permissions
+permited||permitted
peroid||period
persistance||persistence
persistant||persistent
@@ -1334,6 +1348,7 @@ sacrifying||sacrificing
safly||safely
safty||safety
satify||satisfy
+satisifed||satisfied
savable||saveable
scaleing||scaling
scaned||scanned
@@ -1558,6 +1573,7 @@ tunning||tuning
ture||true
tyep||type
udpate||update
+updtes||updates
uesd||used
unknwon||unknown
uknown||unknown
@@ -1614,6 +1630,7 @@ unuseful||useless
unvalid||invalid
upate||update
upsupported||unsupported
+upto||up to
useable||usable
usefule||useful
usefull||useful
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 2e756bee1fa9..ea31640b2671 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -17,6 +17,13 @@ ignore="$(echo "$RCS_FIND_IGNORE" | sed 's|\\||g' )"
# tags and cscope files should also ignore MODVERSION *.mod.c files
ignore="$ignore ( -name *.mod.c ) -prune -o"
+# ignore arbitrary directories
+if [ -n "${IGNORE_DIRS}" ]; then
+ for i in ${IGNORE_DIRS}; do
+ ignore="${ignore} ( -path $i ) -prune -o"
+ done
+fi
+
# Use make KBUILD_ABS_SRCTREE=1 {tags|cscope}
# to force full paths for a non-O= build
if [ "${srctree}" = "." -o -z "${srctree}" ]; then
@@ -91,7 +98,7 @@ all_compiled_sources()
{
echo include/generated/autoconf.h
find $ignore -name "*.cmd" -exec \
- grep -Poh '(?(?=^source_.* \K).*|(?=^ \K\S).*(?= \\))' {} \+ |
+ sed -n -E 's/^source_.* (.*)/\1/p; s/^ (\S.*) \\/\1/p' {} \+ |
awk '!a[$0]++'
} | xargs realpath -esq $([ -z "$KBUILD_ABS_SRCTREE" ] && echo --relative-to=.) |
sort -u
@@ -264,10 +271,12 @@ exuberant()
--$CTAGS_EXTRA=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \
"${regex[@]}"
- setup_regex exuberant kconfig
- all_kconfigs | xargs $1 -a \
- --langdef=kconfig --language-force=kconfig "${regex[@]}"
-
+ KCONFIG_ARGS=()
+ if ! $1 --list-languages | grep -iq kconfig; then
+ setup_regex exuberant kconfig
+ KCONFIG_ARGS=(--langdef=kconfig --language-force=kconfig "${regex[@]}")
+ fi
+ all_kconfigs | xargs $1 -a "${KCONFIG_ARGS[@]}"
}
emacs()
diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py
index 438516bdfb3c..42fa87300941 100755
--- a/scripts/tracing/draw_functrace.py
+++ b/scripts/tracing/draw_functrace.py
@@ -12,9 +12,9 @@ calls. Only the functions's names and the call time are provided.
Usage:
Be sure that you have CONFIG_FUNCTION_TRACER
- # mount -t debugfs nodev /sys/kernel/debug
- # echo function > /sys/kernel/debug/tracing/current_tracer
- $ cat /sys/kernel/debug/tracing/trace_pipe > ~/raw_trace_func
+ # mount -t tracefs nodev /sys/kernel/tracing
+ # echo function > /sys/kernel/tracing/current_tracer
+ $ cat /sys/kernel/tracing/trace_pipe > ~/raw_trace_func
Wait some times but not too much, the script is a bit slow.
Break the pipe (Ctrl + Z)
$ scripts/tracing/draw_functrace.py < ~/raw_trace_func > draw_functrace
diff --git a/scripts/tracing/ftrace-bisect.sh b/scripts/tracing/ftrace-bisect.sh
index 926701162bc8..bb4f59262bbe 100755
--- a/scripts/tracing/ftrace-bisect.sh
+++ b/scripts/tracing/ftrace-bisect.sh
@@ -12,7 +12,7 @@
# (note, if this is a problem with function_graph tracing, then simply
# replace "function" with "function_graph" in the following steps).
#
-# # cd /sys/kernel/debug/tracing
+# # cd /sys/kernel/tracing
# # echo schedule > set_ftrace_filter
# # echo function > current_tracer
#
@@ -20,22 +20,40 @@
#
# # echo nop > current_tracer
#
-# # cat available_filter_functions > ~/full-file
+# Starting with v5.1 this can be done with numbers, making it much faster:
+#
+# The old (slow) way, for kernels before v5.1.
+#
+# [old-way] # cat available_filter_functions > ~/full-file
+#
+# [old-way] *** Note *** this process will take several minutes to update the
+# [old-way] filters. Setting multiple functions is an O(n^2) operation, and we
+# [old-way] are dealing with thousands of functions. So go have coffee, talk
+# [old-way] with your coworkers, read facebook. And eventually, this operation
+# [old-way] will end.
+#
+# The new way (using numbers) is an O(n) operation, and usually takes less than a second.
+#
+# seq `wc -l available_filter_functions | cut -d' ' -f1` > ~/full-file
+#
+# This will create a sequence of numbers that match the functions in
+# available_filter_functions, and when echoing in a number into the
+# set_ftrace_filter file, it will enable the corresponding function in
+# O(1) time. Making enabling all functions O(n) where n is the number of
+# functions to enable.
+#
+# For either the new or old way, the rest of the operations remain the same.
+#
# # ftrace-bisect ~/full-file ~/test-file ~/non-test-file
# # cat ~/test-file > set_ftrace_filter
#
-# *** Note *** this will take several minutes. Setting multiple functions is
-# an O(n^2) operation, and we are dealing with thousands of functions. So go
-# have coffee, talk with your coworkers, read facebook. And eventually, this
-# operation will end.
-#
# # echo function > current_tracer
#
# If it crashes, we know that ~/test-file has a bad function.
#
# Reboot back to test kernel.
#
-# # cd /sys/kernel/debug/tracing
+# # cd /sys/kernel/tracing
# # mv ~/test-file ~/full-file
#
# If it didn't crash.