diff options
author | Mateusz Guzik <mjg@FreeBSD.org> | 2019-12-16 00:07:51 +0000 |
---|---|---|
committer | Mateusz Guzik <mjg@FreeBSD.org> | 2019-12-16 00:07:51 +0000 |
commit | 61f67f32c714638adb441ab95257f2c3531387bd (patch) | |
tree | bf2b1ef989d248ad68387a9079d7b04b91025695 /sys/tools | |
parent | 6fa079fc3f5e7e120f166420c6f0c60f701ba9ae (diff) | |
download | src-test2-61f67f32c714638adb441ab95257f2c3531387bd.tar.gz src-test2-61f67f32c714638adb441ab95257f2c3531387bd.zip |
vfs: allow tail call optimisation in vops in the common case
Most frequently used vops boil down to checking SDT probes, doing the call and
checking again. There is no vop_post/pre in their case but the check after the
call prevents tail call optimisation from taking place. Instead, check once
upfront. Kernels with debug or vops with non-empty vop_post still don't short
circuit.
Reviewed by: kib
Tested by: pho
Differential Revision: https://reviews.freebsd.org/D22739
Notes
Notes:
svn path=/head/; revision=355791
Diffstat (limited to 'sys/tools')
-rw-r--r-- | sys/tools/vnode_if.awk | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/sys/tools/vnode_if.awk b/sys/tools/vnode_if.awk index 39f7f6013a0b..df3251090b99 100644 --- a/sys/tools/vnode_if.awk +++ b/sys/tools/vnode_if.awk @@ -363,16 +363,20 @@ while ((getline < srcfile) > 0) { printc("\tVNASSERT(a->a_gen.a_desc == &" name "_desc, a->a_" args[0]","); printc("\t (\"Wrong a_desc in " name "(%p, %p)\", a->a_" args[0]", a));"); printc("\tVNASSERT(vop != NULL, a->a_" args[0]", (\"No "name"(%p, %p)\", a->a_" args[0]", a));") - printc("\tSDT_PROBE2(vfs, vop, " name ", entry, a->a_" args[0] ", a);\n"); - for (i = 0; i < numargs; ++i) - add_debug_code(name, args[i], "Entry", "\t"); printc("\tKTR_START" ctrstr); add_pre(name); - printc("\tif (vop->"name" != NULL)") + for (i = 0; i < numargs; ++i) + add_debug_code(name, args[i], "Entry", "\t"); + printc("\tif (__predict_true(!SDT_PROBES_ENABLED() && vop->"name" != NULL)) {"); printc("\t\trc = vop->"name"(a);") - printc("\telse") - printc("\t\trc = vop->vop_bypass(&a->a_gen);") - printc("\tSDT_PROBE3(vfs, vop, " name ", return, a->a_" args[0] ", a, rc);\n"); + printc("\t} else {") + printc("\t\tSDT_PROBE2(vfs, vop, " name ", entry, a->a_" args[0] ", a);"); + printc("\t\tif (vop->"name" != NULL)") + printc("\t\t\trc = vop->"name"(a);") + printc("\t\telse") + printc("\t\t\trc = vop->vop_bypass(&a->a_gen);") + printc("\t\tSDT_PROBE3(vfs, vop, " name ", return, a->a_" args[0] ", a, rc);"); + printc("\t}") printc("\tif (rc == 0) {"); for (i = 0; i < numargs; ++i) add_debug_code(name, args[i], "OK", "\t\t"); |