Skip to content

Commit

Permalink
dtrace: move _sdt_probes array into a separately-compiled file
Browse files Browse the repository at this point in the history
This means we no longer need to worry about whether Linux kernel headers
include prototypes that we are declaring probes for, and can just
unconditionally declare them.  Having an exclusion list turned out to
be untenable, because the set of headers transitively included from
<linux/module.h> depends on kernel configuration as well as
architecture: but *.sdtinfo.c only depends on <linux/sdt.h>, which is
entirely under our control and we know includes no prototypes of
anything that we might ever want to probe.  We generate a separate
.h file that only includes _sdt_probec and an extern definition
of _sdt_probes, and include that from the .mod.c: the full definition of
_sdt_probec is now separately compiled

One downside is that we lie to make slightly now, telling it that
*.mod.c depends on *.sdtinfo.c, when actually it depends on *.sdtinfo.h:
but the two are generated by the same script at the same time so this
isn't going to cause a problem.

Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
  • Loading branch information
nickalcock committed Oct 12, 2020
1 parent 0236c7f commit c731ef8
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,5 @@ x509.genkey
# Generated DTrace SDT files
#
*.sdtinfo.c
*.sdtinfo.h
*.sdtstub.S
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1861,7 +1861,7 @@ clean: $(clean-dirs)
-o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
-o -name '*.dwo' -o -name '*.lst' \
-o -name '*.su' -o -name '*.mod' \
-o -name '*.sdtinfo.c' -o -name '*.sdtstub.S' \
-o -name '*.sdtinfo.c' -o -name '*.sdtinfo.h' -o -name '*.sdtstub.S' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.lex.c' -o -name '*.tab.[ch]' \
-o -name '*.asn1.[ch]' \
Expand Down
7 changes: 5 additions & 2 deletions scripts/Makefile.modfinal
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ ifdef CONFIG_DTRACE
sdtgen = $(srctree)/scripts/dtrace_sdt.sh

quiet_cmd_sdtinfo = SDTINF $@
cmd_sdtinfo = $(sdtgen) sdtinfo $@ $< kmod
cmd_sdtinfo = $(sdtgen) sdtinfo $@ $< kmod $(@:.c=.h)

quiet_cmd_sdtstub = SDTSTB $@
cmd_sdtstub = $(sdtgen) sdtstub $@ $<
Expand All @@ -56,6 +56,9 @@ $(modules:.ko=.sdtinfo.c): %.sdtinfo.c: %.o %.mod.c
$(modules:.ko=.sdtstub.S) : %.sdtstub.S: %.o %.sdtinfo.c
$(call cmd,sdtstub)

%.sdtinfo.o : %.sdtinfo.c
$(call if_changed_dep,cc_o_c)

%.mod.o: %.mod.c %.sdtinfo.c FORCE
$(call if_changed_dep,cc_o_c)

Expand Down Expand Up @@ -210,7 +213,7 @@ quiet_cmd_ld_ko_o = LD [M] $@
$(OBJCOPY) $(module-ctf-flags) $@.tmp $@ && rm -f $@.tmp ; \
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)

$(modules): %.ko: %.o %.mod.o $(KBUILD_LDS_MODULE) $(module-sdt-modular-prereq) $(module-ctfs-modular-prereq) FORCE
$(modules): %.ko: %.o %.mod.o %.sdtinfo.o $(KBUILD_LDS_MODULE) $(module-sdt-modular-prereq) $(module-ctfs-modular-prereq) FORCE
$(call cmd_touch_ctf)
+$(call if_changed,ld_ko_o)

Expand Down
30 changes: 14 additions & 16 deletions scripts/dtrace_sdt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ LANG=C
# dtrace_sdt.sh sdtstub <S-file> <o-file>+
# This is used to generate DTrace SDT probe stubs based on one
# or more object file(s). The stubs are written to <S-file>.
# dtrace_sdt.sh sdtinfo <c-file> <o-file> kmod
# dtrace_sdt.sh sdtinfo <c-file> <o-file> kmod <h-file>
# This is used to generate DTrace SDT probe definitions for a
# kmod .o file. The output is written to <c-file>.
# kmod .o file. The output is written to <c-file> and <h-file>.
# dtrace_sdt.sh sdtinfo <S-file> <l-file>
# This is used to generate DTrace SDT probe definitions for a
# linked kernel image file <l-file>. The output is written to
Expand Down Expand Up @@ -71,6 +71,8 @@ if [ "$opr" != "sdtinfo" ]; then
fi

if [ "$tok" = "kmod" ]; then
hfile="$3"

# Pre-process the object file to handle any local functions that contain
# SDT probes.
scripts/kmodsdt ${ofn}
Expand Down Expand Up @@ -143,7 +145,7 @@ if [ "$tok" = "kmod" ]; then
print $4 " " $1 " F " $6;
}' | \
sort -k1,2 | \
gawk -v arch=${ARCH} \
gawk -v arch=${ARCH} -v hfile=${hfile} \
'function subl(v0, v1, v0h, v0l, v1h, v1l, d, tmp) {
tmp = $0;
if (length(v0) > 8) {
Expand Down Expand Up @@ -185,7 +187,6 @@ if [ "$tok" = "kmod" ]; then
BEGIN {
print "#include <linux/sdt.h>";
print "#include <linux/fs.h>";
probec = 0;
}
Expand Down Expand Up @@ -240,18 +241,15 @@ if [ "$tok" = "kmod" ]; then
}
END {
if (probec > 0) {
for (alias in protom)
if (alias != "locks_start_grace" && alias != "locks_end_grace")
printf "extern void %s(void);\n", alias;
print "\nstatic struct sdt_probedesc\t_sdt_probes[] = {";
for (i = 0; i < probec; i++)
print probev[i];
print "};\n";
} else
print "#define _sdt_probes\tNULL";
print "#define _sdt_probec\t" probec;
for (alias in protom)
printf "extern void %s(void);\n", alias;
print "\nstruct sdt_probedesc\t_sdt_probes[] = {";
for (i = 0; i < probec; i++)
print probev[i];
print "};\n";
print "#define _sdt_probec\t" probec > hfile;
print "extern struct sdt_probedesc _sdt_probes[];" >> hfile;
exit(errc == 0 ? 0 : 1);
}' > $tfn
Expand Down
2 changes: 1 addition & 1 deletion scripts/mod/modpost.c
Original file line number Diff line number Diff line change
Expand Up @@ -2258,7 +2258,7 @@ static void add_header(struct buffer *b, struct module *mod)
buf_printf(b, "#include <linux/compiler.h>\n");
buf_printf(b, "\n");
buf_printf(b, "#ifdef CONFIG_DTRACE\n");
buf_printf(b, "# include \"%s.sdtinfo.c\"\n", modname);
buf_printf(b, "# include \"%s.sdtinfo.h\"\n", modname);
buf_printf(b, "#endif\n");
buf_printf(b, "\n");
buf_printf(b, "BUILD_SALT;\n");
Expand Down

0 comments on commit c731ef8

Please sign in to comment.