2009-09-24 20:02:18 +04:00
# ifndef __PERF_THREAD_H
# define __PERF_THREAD_H
2015-04-07 17:59:50 +03:00
# include <linux/atomic.h>
2009-08-14 14:21:53 +04:00
# include <linux/rbtree.h>
2013-09-11 18:56:44 +04:00
# include <linux/list.h>
2009-08-14 14:21:53 +04:00
# include <unistd.h>
2012-10-06 22:43:20 +04:00
# include <sys/types.h>
2009-08-14 14:21:53 +04:00
# include "symbol.h"
2013-11-19 00:32:47 +04:00
# include <strlist.h>
2015-03-24 18:52:41 +03:00
# include <intlist.h>
2009-08-14 14:21:53 +04:00
2014-10-30 17:09:42 +03:00
struct thread_stack ;
2016-06-03 06:33:12 +03:00
struct unwind_libunwind_ops ;
2014-10-30 17:09:42 +03:00
2009-12-11 19:50:36 +03:00
struct thread {
2010-06-17 15:37:44 +04:00
union {
struct rb_node rb_node ;
struct list_head node ;
} ;
2014-03-22 00:57:01 +04:00
struct map_groups * mg ;
2013-08-26 17:00:19 +04:00
pid_t pid_ ; /* Not all tools update this */
2013-07-04 17:20:31 +04:00
pid_t tid ;
2013-05-26 08:47:10 +04:00
pid_t ppid ;
2014-07-22 17:17:24 +04:00
int cpu ;
2015-04-07 17:59:50 +03:00
atomic_t refcnt ;
2009-09-16 19:40:48 +04:00
char shortname [ 3 ] ;
2010-02-20 04:02:07 +03:00
bool comm_set ;
perf tools: Elliminate alignment holes
perf_evsel:
Before:
/* size: 320, cachelines: 5, members: 35 */
/* sum members: 304, holes: 3, sum holes: 16 */
After:
/* size: 304, cachelines: 5, members: 35 */
/* last cacheline: 48 bytes */
perf_evlist:
Before:
/* size: 2544, cachelines: 40, members: 17 */
/* sum members: 2533, holes: 2, sum holes: 11 */
/* last cacheline: 48 bytes */
After:
/* size: 2536, cachelines: 40, members: 17 */
/* sum members: 2533, holes: 1, sum holes: 3 */
/* last cacheline: 40 bytes */
timechart:
Before:
/* size: 288, cachelines: 5, members: 21 */
/* sum members: 271, holes: 2, sum holes: 10 */
/* padding: 7 */
/* last cacheline: 32 bytes */
After:
/* size: 272, cachelines: 5, members: 21 */
/* sum members: 271, holes: 1, sum holes: 1 */
/* last cacheline: 16 bytes */
thread:
Before:
/* size: 112, cachelines: 2, members: 15 */
/* sum members: 101, holes: 2, sum holes: 11 */
/* last cacheline: 48 bytes */
After:
/* size: 104, cachelines: 2, members: 15 */
/* sum members: 101, holes: 1, sum holes: 3 */
/* last cacheline: 40 bytes */
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-a543w7zjl9yyrg9nkf1teukp@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-05-15 23:29:56 +03:00
int comm_len ;
2013-08-14 18:49:27 +04:00
bool dead ; /* if set thread has exited */
2013-09-11 18:56:44 +04:00
struct list_head comm_list ;
2014-10-23 14:45:13 +04:00
u64 db_id ;
perf kvm: Events analysis tool
Add 'perf kvm stat' support to analyze kvm vmexit/mmio/ioport smartly
Usage:
- kvm stat
run a command and gather performance counter statistics, it is the alias of
perf stat
- trace kvm events:
perf kvm stat record, or, if other tracepoints are interesting as well, we
can append the events like this:
perf kvm stat record -e timer:* -a
If many guests are running, we can track the specified guest by using -p or
--pid, -a is used to track events generated by all guests.
- show the result:
perf kvm stat report
The output example is following:
13005
13059
total 2 guests are running on the host
Then, track the guest whose pid is 13059:
^C[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.253 MB perf.data.guest (~11065 samples) ]
See the vmexit events:
Analyze events for all VCPUs:
VM-EXIT Samples Samples% Time% Avg time
APIC_ACCESS 460 70.55% 0.01% 22.44us ( +- 1.75% )
HLT 93 14.26% 99.98% 832077.26us ( +- 10.42% )
EXTERNAL_INTERRUPT 64 9.82% 0.00% 35.35us ( +- 14.21% )
PENDING_INTERRUPT 24 3.68% 0.00% 9.29us ( +- 31.39% )
CR_ACCESS 7 1.07% 0.00% 8.12us ( +- 5.76% )
IO_INSTRUCTION 3 0.46% 0.00% 18.00us ( +- 11.79% )
EXCEPTION_NMI 1 0.15% 0.00% 5.83us ( +- -nan% )
Total Samples:652, Total events handled time:77396109.80us.
See the mmio events:
Analyze events for all VCPUs:
MMIO Access Samples Samples% Time% Avg time
0xfee00380:W 387 84.31% 79.28% 8.29us ( +- 3.32% )
0xfee00300:W 24 5.23% 9.96% 16.79us ( +- 1.97% )
0xfee00300:R 24 5.23% 7.83% 13.20us ( +- 3.00% )
0xfee00310:W 24 5.23% 2.93% 4.94us ( +- 3.84% )
Total Samples:459, Total events handled time:4044.59us.
See the ioport event:
Analyze events for all VCPUs:
IO Port Access Samples Samples% Time% Avg time
0xc050:POUT 3 100.00% 100.00% 13.75us ( +- 10.83% )
Total Samples:3, Total events handled time:41.26us.
And, --vcpu is used to track the specified vcpu and --key is used to sort the
result:
Analyze events for VCPU 0:
VM-EXIT Samples Samples% Time% Avg time
HLT 27 13.85% 99.97% 405790.24us ( +- 12.70% )
EXTERNAL_INTERRUPT 13 6.67% 0.00% 27.94us ( +- 22.26% )
APIC_ACCESS 146 74.87% 0.03% 21.69us ( +- 2.91% )
IO_INSTRUCTION 2 1.03% 0.00% 17.77us ( +- 20.56% )
CR_ACCESS 2 1.03% 0.00% 8.55us ( +- 6.47% )
PENDING_INTERRUPT 5 2.56% 0.00% 6.27us ( +- 3.94% )
Total Samples:195, Total events handled time:10959950.90us.
Signed-off-by: Dong Hao <haodong@linux.vnet.ibm.com>
Signed-off-by: Runzhen Wang <runzhen@linux.vnet.ibm.com>
[ Dong Hao <haodong@linux.vnet.ibm.com>
Runzhen Wang <runzhen@linux.vnet.ibm.com>:
- rebase it on current acme's tree
- fix the compiling-error on i386 ]
Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Acked-by: David Ahern <dsahern@gmail.com>
Cc: Avi Kivity <avi@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: kvm@vger.kernel.org
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/1347870675-31495-4-git-send-email-haodong@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2012-09-17 12:31:15 +04:00
void * priv ;
2014-10-30 17:09:42 +03:00
struct thread_stack * ts ;
2016-04-07 10:11:12 +03:00
# ifdef HAVE_LIBUNWIND_SUPPORT
2016-06-03 06:33:12 +03:00
void * addr_space ;
struct unwind_libunwind_ops * unwind_libunwind_ops ;
2016-04-07 10:11:12 +03:00
# endif
2009-08-14 14:21:53 +04:00
} ;
2011-11-28 13:56:39 +04:00
struct machine ;
2013-09-13 11:28:57 +04:00
struct comm ;
2010-03-26 01:58:58 +03:00
2013-08-26 17:00:19 +04:00
struct thread * thread__new ( pid_t pid , pid_t tid ) ;
2014-04-09 22:54:29 +04:00
int thread__init_map_groups ( struct thread * thread , struct machine * machine ) ;
2013-11-05 22:32:36 +04:00
void thread__delete ( struct thread * thread ) ;
2015-03-03 04:21:35 +03:00
struct thread * thread__get ( struct thread * thread ) ;
void thread__put ( struct thread * thread ) ;
static inline void __thread__zput ( struct thread * * thread )
{
thread__put ( * thread ) ;
* thread = NULL ;
}
# define thread__zput(thread) __thread__zput(&thread)
2013-08-14 18:49:27 +04:00
static inline void thread__exited ( struct thread * thread )
{
thread - > dead = true ;
}
2010-07-31 01:28:42 +04:00
2014-07-31 10:00:44 +04:00
int __thread__set_comm ( struct thread * thread , const char * comm , u64 timestamp ,
bool exec ) ;
static inline int thread__set_comm ( struct thread * thread , const char * comm ,
u64 timestamp )
{
return __thread__set_comm ( thread , comm , timestamp , false ) ;
}
2016-04-26 18:32:50 +03:00
int thread__set_comm_from_proc ( struct thread * thread ) ;
2013-11-05 22:32:36 +04:00
int thread__comm_len ( struct thread * thread ) ;
2013-09-13 11:28:57 +04:00
struct comm * thread__comm ( const struct thread * thread ) ;
2014-07-31 10:00:44 +04:00
struct comm * thread__exec_comm ( const struct thread * thread ) ;
2013-09-11 16:46:56 +04:00
const char * thread__comm_str ( const struct thread * thread ) ;
2016-06-03 06:33:13 +03:00
int thread__insert_map ( struct thread * thread , struct map * map ) ;
2013-09-11 18:18:24 +04:00
int thread__fork ( struct thread * thread , struct thread * parent , u64 timestamp ) ;
2012-12-08 00:39:39 +04:00
size_t thread__fprintf ( struct thread * thread , FILE * fp ) ;
2009-09-24 20:02:18 +04:00
2016-05-24 03:52:24 +03:00
struct thread * thread__main_thread ( struct machine * machine , struct thread * thread ) ;
2014-10-23 19:50:25 +04:00
void thread__find_addr_map ( struct thread * thread ,
2011-11-28 13:56:39 +04:00
u8 cpumode , enum map_type type , u64 addr ,
2013-08-08 15:32:27 +04:00
struct addr_location * al ) ;
2010-01-15 04:45:29 +03:00
2014-10-23 19:50:25 +04:00
void thread__find_addr_location ( struct thread * thread ,
2011-11-28 13:56:39 +04:00
u8 cpumode , enum map_type type , u64 addr ,
2013-08-08 15:32:26 +04:00
struct addr_location * al ) ;
2013-06-08 02:22:12 +04:00
2014-03-11 23:16:49 +04:00
void thread__find_cpumode_addr_location ( struct thread * thread ,
enum map_type type , u64 addr ,
struct addr_location * al ) ;
2013-06-08 02:22:12 +04:00
static inline void * thread__priv ( struct thread * thread )
{
return thread - > priv ;
}
static inline void thread__set_priv ( struct thread * thread , void * p )
{
thread - > priv = p ;
}
2013-11-19 00:32:47 +04:00
static inline bool thread__is_filtered ( struct thread * thread )
{
if ( symbol_conf . comm_list & &
! strlist__has_entry ( symbol_conf . comm_list , thread__comm_str ( thread ) ) ) {
return true ;
}
2015-03-24 18:52:41 +03:00
if ( symbol_conf . pid_list & &
! intlist__has_entry ( symbol_conf . pid_list , thread - > pid_ ) ) {
return true ;
}
if ( symbol_conf . tid_list & &
! intlist__has_entry ( symbol_conf . tid_list , thread - > tid ) ) {
return true ;
}
2013-11-19 00:32:47 +04:00
return false ;
}
2009-09-24 20:02:18 +04:00
# endif /* __PERF_THREAD_H */