From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8974 invoked by alias); 6 Mar 2013 10:11:47 -0000 Received: (qmail 8961 invoked by uid 22791); 6 Mar 2013 10:11:45 -0000 X-SWARE-Spam-Status: No, hits=-3.4 required=5.0 tests=AWL,BAYES_00,KHOP_THREADED,RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from sibelius.xs4all.nl (HELO glazunov.sibelius.xs4all.nl) (83.163.83.176) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 06 Mar 2013 10:11:37 +0000 Received: from glazunov.sibelius.xs4all.nl (kettenis@localhost [127.0.0.1]) by glazunov.sibelius.xs4all.nl (8.14.5/8.14.3) with ESMTP id r26ABVWf010754; Wed, 6 Mar 2013 11:11:31 +0100 (CET) Received: (from kettenis@localhost) by glazunov.sibelius.xs4all.nl (8.14.5/8.14.3/Submit) id r26ABVD9026584; Wed, 6 Mar 2013 11:11:31 +0100 (CET) Date: Wed, 06 Mar 2013 10:11:00 -0000 Message-Id: <201303061011.r26ABVD9026584@glazunov.sibelius.xs4all.nl> From: Mark Kettenis To: markus.t.metzger@intel.com CC: gdb-patches@sourceware.org, markus.t.metzger@gmail.com In-reply-to: <1362416770-19750-3-git-send-email-markus.t.metzger@intel.com> (message from Markus Metzger on Mon, 4 Mar 2013 18:05:49 +0100) Subject: Re: [patch v9 02/23] linux, btrace: perf_event based branch tracing References: <1362416770-19750-1-git-send-email-markus.t.metzger@intel.com> <1362416770-19750-3-git-send-email-markus.t.metzger@intel.com> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2013-03/txt/msg00204.txt.bz2 > From: Markus Metzger > Date: Mon, 4 Mar 2013 18:05:49 +0100 > > Implement branch tracing on Linux based on perf_event such taht it > can be shared between gdb and gdbserver. > > The actual btrace target ops will be implemented on top. > > 2013-03-04 Markus Metzger > > * common/linux_btrace.h: New file. > * common/linux_btrace.c: New file. > * Makefile.in (SFILES): Add btrace.c. > (HFILES_NO_SRCDIR): Add common/linux-btrace.h. > (COMMON_OBS): Add btrace.o. > (linux-btrace.o): New rule. > > gdbserver/ > * Makefile.in (SFILES): Add $(srcdir)/common/linux-btrace.c. > (linux_btrace_h): New variable. > (linux-btrace.o): New rule. > +/* See linux-btrace.h. */ > + > +VEC (btrace_block_s) * > +linux_read_btrace (struct btrace_target_info *tinfo) > +{ > + VEC (btrace_block_s) *btrace = NULL; > + volatile struct perf_event_mmap_page *header; > + const uint8_t *begin, *end, *start; > + unsigned long data_head, retries = 5; > + size_t buffer_size; > + > + header = perf_event_header (tinfo); > + buffer_size = perf_event_buffer_size (tinfo); > + > + /* We may need to retry reading the trace. See below. */ > + while (retries--) > + { > + data_head = header->data_head; > + > + /* Make sure the trace data is up-to-date. */ > + memory_barrier (); The barrier here makes absolutely no sense to me. It's only a compiler barrier and declaring header as volatile should be enough to force the compiler to fetch HEADER->data_head from memory. > + > + /* If there's new trace, let's read it. */ > + if (data_head != tinfo->data_head) > + { > + /* Data_head keeps growing; the buffer itself is circular. */ > + begin = perf_event_buffer_begin (tinfo); > + start = begin + data_head % buffer_size; > + > + if (data_head <= buffer_size) > + end = start; > + else > + end = perf_event_buffer_end (tinfo); > + > + btrace = perf_event_read_bts (tinfo, begin, end, start); > + } > + > + /* The stopping thread notifies its ptracer before it is scheduled out. > + On multi-core systems, the debugger might therefore run while the > + kernel might be writing the last branch trace records. > + > + Let's check whether the data head moved while we read the trace. */ > + if (data_head == header->data_head) > + break; > + }