public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jason Baron <jbaron@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: mathieu.desnoyers@polymtl.ca, roland@redhat.com, rth@redhat.com,
	mingo@elte.hu
Subject: [PATCH 0/4] RFC: jump label - (tracepoint optimizations)
Date: Thu, 3 Sep 2009 16:25:50 -0400	[thread overview]
Message-ID: <cover.1252007851.git.jbaron@redhat.com> (raw)

hi,

Problem:

Currenly, tracepoints are implemented using a conditional. The conditional
check requires checking a global variable for each tracepoint. Although,
the overhead of this check is small, it increases under memory pressure. As we
increase the number of tracepoints in the kernel this may become more of an
issue. In addition, tracepoints are often dormant (disabled), and provide no
direct kernel functionality. Thus, it is highly desirable to reduce their
impact as much as possible. Mathieu Desnoyers has already suggested a number of
requirements for a solution to this issue.

Solution:

In discussing this problem with Roland McGrath and Richard Henderson, we came 
up with a new 'asm goto' statement that allows branching to a label. Thus, this
patch set introdues a 'STATIC_JUMP_IF()' macro as follows:

#ifdef HAVE_STATIC_JUMP

#define STATIC_JUMP_IF(tag, label, cond)                               \
       asm goto ("1:"   /* 5-byte insn */                              \
          P6_NOP5                                                      \
               ".pushsection __jump_table,  \"a\" \n\t"                \
               _ASM_PTR "1b, %l[" #label "], %c0 \n\t"                 \
               ".popsection \n\t"                                      \
               : :  "i" (__sjstrtab_##tag) :  : label)

#else

#define STATIC_JUMP_IF(tag, label, cond)        \
        if (unlikely(cond))                     \
                goto label;

#endif /* !HAVE_STATIC_JUMP */


which can be used as:

        STATIC_JUMP_IF(trace, trace_label, jump_enabled);
        printk("not doing tracing\n");
if (0) {
trace_label:
        printk("doing tracing: %d\n", file);
}

---------------------------------------

Thus, if 'HAVE_STATIC_JUMP' is defined (which will depend ultimately on the
existence of 'asm goto' in the compiler version), we simply have a no-op
followed by a jump around the dormant (disabled) tracing code. The
'STATIC_JUMP_IF()' macro, produces a 'jump_table' which has the following
format:

[instruction address] [jump target] [tracepoint name]

Thus, to enable a tracepoint, we simply patch the 'instruction address' with
a jump to the 'jump target'. The current implementation is using ftrace
infrastructure to accomplish the patching, which uses 'stop_machine'. In
subsequent versions, we will update the mechanism to use more efficient
code patching techniques.

I've tested the performance of this using 'get_cycles()' calls around the
tracepoint call sites. For an Intel Core 2 Quad cpu (in cycles, averages):
		
		idle		after tbench run
		----		----------------
old code	 32		  88
new code	  2		   4


The performance improvement can be reproduced very reliably (using patch 4
in this series) on both Intel and AMD hardware.

In terms of code analysis the current code for the disabled case is a 'cmpl'
followed by a 'je' around the tracepoint code. so:

cmpl - 83 3d 0e 77 87 00 00 - 7 bytes
je   - 74 3e                - 2 bytes

total of 9 instruction bytes.

The new code is a 'nopl' followed by a 'jmp'. Thus:

nopl - 0f 1f 44 00 00 - 5 bytes
jmp  - eb 3e          - 2 bytes

total of 7 instruction bytes.

So, the new code also accounts for 2 less bytes in the instruction cache per tracepoint.

here's a link to the gcc thread introducing this feature:

http://gcc.gnu.org/ml/gcc-patches/2009-07/msg01556.html

Todo:

-convert the patching to a more optimal implementation (not using stop machine)
-expand infrastructure for modules
-other use cases?
-mark the trace_label section with 'cold' attributes
-add module support
-add support for other arches (besides x86)

thanks,

-Jason

 arch/x86/kernel/ftrace.c          |   36 +++++
 arch/x86/kernel/test_nx.c         |    3 +
 include/asm-generic/vmlinux.lds.h |   11 ++
 include/linux/ftrace.h            |    3 +
 include/linux/jump_label.h        |   45 ++++++
 include/linux/tracepoint.h        |   50 +++++---
 kernel/Makefile                   |    2 +-
 kernel/jump_label.c               |  271 +++++++++++++++++++++++++++++++++++++
 kernel/trace/trace_workqueue.c    |    2 +
 kernel/tracepoint.c               |  134 ++++++++++++++++++
 10 files changed, 540 insertions(+), 17 deletions(-)
 create mode 100644 include/linux/jump_label.h
 create mode 100644 kernel/jump_label.c


             reply	other threads:[~2009-09-03 20:26 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-03 20:25 Jason Baron [this message]
2009-09-03 20:25 ` [PATCH 1/4] RFC: basic jump label implementation Jason Baron
2009-09-03 20:25 ` [PATCH 2/4] RFC: jump label example usage Jason Baron
2009-09-03 20:26 ` [PATCH 3/4] RFC: implement tracepoints on top of jump patching Jason Baron
2009-09-03 20:26 ` [PATCH 4/4] RFC: performance testing harness Jason Baron
2009-09-03 20:45 ` [PATCH 0/4] RFC: jump label - (tracepoint optimizations) Daniel Walker
2009-09-03 21:01 ` Ingo Molnar
2009-09-03 21:11   ` Roland McGrath
2009-09-07 15:48 ` Mathieu Desnoyers
2009-09-07 17:06   ` Mathieu Desnoyers
2009-09-10 21:15     ` Steven Rostedt
2009-09-08 20:48   ` Jason Baron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cover.1252007851.git.jbaron@redhat.com \
    --to=jbaron@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@polymtl.ca \
    --cc=mingo@elte.hu \
    --cc=roland@redhat.com \
    --cc=rth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox