Jump label
Consider the definition of a typical tracepoint, which, behind all of the preprocessor madness, looks something like:
static inline trace_foo(args) { if (unlikely(trace_foo_enabled)) goto do_trace; return; do_trace: /* Actually do tracing stuff */ }
The cost of a test for a single tracepoint is essentially zero. The number of tracepoints in the kernel is growing, though, and each one adds a new test. Each test must fetch a value from memory, adding to the pressure on the cache and hurting performance. Given that the value almost never changes, it would be nice to find a way to optimize the "tracepoint disabled" case.
In 2.6.37, this tracepoint can be rewritten using a new macro:
#include <linux/jump_label.h> #define JUMP_LABEL(key, label) \ if (unlikely(*key)) \ goto label;
The nice thing is that JUMP_LABEL() does not have to be implemented like that. It can, instead, (1) note the location of the test and the key value in a special table, and (2) simply insert a no-op instruction. That reduces the cost of the test (and the tracepoint) to zero for the common "not enabled" case. Most of the time, the tracepoint will never be enabled and the omitted test will never be missed.
The tricky part happens when somebody wants to enable the tracepoint. Changing its status now requires calling one of a pair of special functions:
void enable_jump_label(void *key); void disable_jump_label(void *key);
A call to enable_jump_label() will look up the key in the jump label table, then replace the special no-op instructions with the assembly equivalent of "goto label", enabling the tracepoint. Disabling the jump label will cause the no-op instruction to be restored.
The end result is a significant reduction in the overhead of disabled
tracepoints. This feature only works on architectures which support it
(x86 only, at the moment) and only with relatively recent versions of GCC;
otherwise the preprocessor version is used.
Index entries for this article | |
---|---|
Kernel | Jump label |
Posted Oct 28, 2010 5:37 UTC (Thu)
by daney (guest, #24551)
[Link] (2 responses)
1) Jump label works on SPARC and MIPS too, not just x86.
2) Jump label doesn't work anywhere reliably due to bugs in current GCC releases.
Posted Oct 28, 2010 21:41 UTC (Thu)
by nevets (subscriber, #11875)
[Link] (1 responses)
Posted Oct 29, 2010 21:18 UTC (Fri)
by daney (guest, #24551)
[Link]
Posted Oct 28, 2010 7:19 UTC (Thu)
by epa (subscriber, #39769)
[Link] (2 responses)
Posted Oct 29, 2010 11:11 UTC (Fri)
by marcH (subscriber, #57642)
[Link] (1 responses)
Posted Oct 29, 2010 15:31 UTC (Fri)
by nix (subscriber, #2304)
[Link]
Posted Oct 28, 2010 7:40 UTC (Thu)
by tcourbon (guest, #60669)
[Link] (4 responses)
(Furthermore does the x86 architecture include x86_64 ? If not it looks, again, over complicated for a not so impressive expected result.)
Posted Oct 28, 2010 13:22 UTC (Thu)
by CChittleborough (subscriber, #60775)
[Link] (2 responses)
Posted Oct 28, 2010 14:50 UTC (Thu)
by nix (subscriber, #2304)
[Link]
Posted Oct 30, 2010 22:05 UTC (Sat)
by giraffedata (guest, #1954)
[Link]
I believe "current kernel" refers to kernel code before the new approach.
I.e. What do we get in return for this complication?
Posted Dec 31, 2010 17:25 UTC (Fri)
by SEJeff (guest, #51588)
[Link]
Posted Oct 28, 2010 7:54 UTC (Thu)
by ptman (subscriber, #57271)
[Link] (4 responses)
Posted Oct 28, 2010 13:09 UTC (Thu)
by i3839 (guest, #31386)
[Link] (2 responses)
Posted Nov 1, 2010 20:58 UTC (Mon)
by ThomasBellman (guest, #67902)
[Link] (1 responses)
Posted Nov 2, 2010 20:28 UTC (Tue)
by i3839 (guest, #31386)
[Link]
Posted Oct 30, 2010 3:50 UTC (Sat)
by compudj (subscriber, #43335)
[Link]
Jump label
Jump label
Jump label
Jump label
Coming soon: JIT
Jump label
Jump label
Jump label
Trade-off
Trade-off
Trade-off
Is there anyway to measure the actual overhead caused by the test in the current kernel ?
With the new approach, there is very little overhead
Jump label
Jump label
Jump label
Jump label
Jump label
Jump label