PAPI 7.1.0.0
Loading...
Searching...
No Matches
perfnec/perfmon.c
Go to the documentation of this file.
1/*
2* File: perfmon.c
3* Author: Philip Mucci
4* mucci@cs.utk.edu
5* Mods: Brian Sheely
6* bsheely@eecs.utk.edu
7*/
8
9/* TODO LIST:
10 - Events for all platforms
11 - Derived events for all platforms
12 - Latency profiling
13 - BTB/IPIEAR sampling
14 - Test on ITA2, Pentium 4
15 - hwd_ntv_code_to_name
16 - Make native map carry major events, not umasks
17 - Enum event uses native_map not pfnec()
18 - Hook up globals to be freed to sub_info
19 - Better feature bit support for IEAR
20*/
21#include <sys/stat.h>
22#include <fcntl.h>
23
24#include "papi.h"
25#include "papi_internal.h"
26#include "papi_vector.h"
27#include "papi_memory.h"
28#include "extras.h"
29
30#include "perfmon/perfmon_nec.h"
31#include "perfnec.h"
32
33#include "linux-memory.h"
34#include "linux-timer.h"
35#include "linux-common.h"
36
37#define PFNECLIB_MAX_PMDS 32
38
39
40static int num_events=0;
41
42static
43int check_pmmr(void)
44{
45 uint64_t pmmr;
46 asm volatile(
47 "smir %0, %pmmr":"=r"(pmmr));
48 if (pmmr != 0x0000000000001000) {
49 fprintf(stderr, "PMMR is not expected: 0x%lx\n", pmmr);
50 return -1;
51 }
52 return PAPI_OK;
53}
54
55static uint64_t diff56(uint64_t after, uint64_t before)
56{
57 return 0x00ffffffffffffff & (after - before);
58}
59
60static uint64_t diff52(uint64_t after, uint64_t before)
61{
62 return 0x000fffffffffffff & (after - before);
63}
64
65
66#define MAX_COUNTERS PFMLIB_MAX_PMCS
67#define MAX_COUNTER_TERMS PFMLIB_MAX_PMCS
68
69/* typedefs to conform to PAPI component layer code. */
70/* these are void * in the PAPI framework layer code. */
73
74
75/* Advance declarations */
76static int _papi_pfnec_set_overflow( EventSetInfo_t * ESI, int EventIndex,
77 int threshold );
79
80
81/* Static locals */
82
84//static pfneclib_regmask_t _perfmon2_pfnec_unavailable_pmcs;
85//static pfneclib_regmask_t _perfmon2_pfnec_unavailable_pmds;
86
87/* Debug functions */
88
89#ifdef DEBUG
90static void
92{
93}
94
95static void
96dump_sets( pfarg_setdesc_t * set, int num_sets )
97{
98}
99
100static void
101dump_setinfo( pfarg_setinfo_t * setinfo, int num_sets )
102{
103}
104
105static void
107{
108}
109
110static void
112{
113}
114
115static void
117{
118}
119
120static void
122{
123}
124#endif
125
126#define PFM_MAX_PMCDS 20
127
128static int
130{
131 return PAPI_OK;
132}
133
134static int
136{
137 return PAPI_OK;
138}
139
140static int
142{
143 return PAPI_OK;
144}
145
146
147/* This routine effectively does argument checking as the real magic will happen
148 in compute_kernel_args. This just gets the value back from the kernel. */
149
150static int
151check_multiplex_timeout( int ctx_fd, unsigned long *timeout_ns )
152{
153 return ( PAPI_OK );
154}
155
156/* The below function is stolen from libpfnec from Stephane Eranian */
157static int
159 pfneclib_regmask_t * r_pmds,
160 unsigned long *timeout_ns )
161{
162 return PAPI_OK;
163}
164
165/* BEGIN COMMON CODE */
166
167static inline int
169{
170 return ( PAPI_OK );
171}
172
173
174static int
175attach( hwd_control_state_t * ctl, unsigned long tid )
176{
177 return ( PAPI_OK );
178}
179
180static int
182{
183 return ( PAPI_OK );
184}
185
186static inline int
187set_domain( hwd_control_state_t * ctl, int domain )
188{
189 return ( compute_kernel_args( ctl ) );
190}
191
192static inline int
193set_granularity( hwd_control_state_t * this_state, int domain )
194{
195 return PAPI_OK;
196}
197
198/* This function should tell your kernel extension that your children
199 inherit performance register information and propagate the values up
200 upon child exit and parent wait. */
201
202static inline int
203set_inherit( int arg )
204{
205 return PAPI_ECMP;
206}
207
208static int
209get_string_from_file( char *file, char *str, int len )
210{
211 return ( PAPI_OK );
212}
213
214static int
216{
217 int e;
218 num_events = 0;
219 int status = check_pmmr();
220 if (PAPI_OK != status) {
221 // do something smart to disable components
222 fprintf(stderr, "Placeholder: component disabled, error in check_pmmr\n");
223 }
224 for ( e = 0; e < PKG_NUM_EVENTS; ++e ) {
225 /* compose string to individual event */
226 size_t ret;
227
228 ret = snprintf(perfnec_ntv_events[num_events].name,
230 "%s", pkg_event_names[e]);
231 if (ret <= 0 || sizeof(perfnec_ntv_events[num_events].name) <= ret) continue;
232 ret = snprintf(perfnec_ntv_events[num_events].description,
233 sizeof(perfnec_ntv_events[num_events].description),
234 "%s", pkg_event_descs[e]);
235 if (ret <= 0 || sizeof(perfnec_ntv_events[num_events].description) <= ret) continue;
236 ret = snprintf(perfnec_ntv_events[num_events].units,
238 "%s", pkg_units[e]);
239 if (ret < 0 || sizeof(perfnec_ntv_events[num_events].name) <= ret) continue;
240
243
245
246 num_events++;
247 }
248
249 // this is statically decided so far.
253
255
256 return PAPI_OK;
257}
258
259static int
261{
262 return PAPI_OK;
263}
264
265static int
267{
268 return ( PAPI_OK );
269}
270
271/* reset the hardware counters */
272static int
274{
275 return ( PAPI_OK );
276}
277
278/* write(set) the hardware counters */
279static int
281 long long *from )
282{
283 return ( PAPI_OK );
284}
285
286static int
288 long long **events, int flags )
289{
290 uint64_t pmc[16];
291 asm volatile(
292 "smir %0,%pmc00\n"
293 "smir %1,%pmc01\n"
294 "smir %2,%pmc02\n"
295 "smir %3,%pmc03\n"
296 "smir %4,%pmc04\n"
297 "smir %5,%pmc05\n"
298 "smir %6,%pmc06\n"
299 "smir %7,%pmc07\n"
300 "smir %8,%pmc08\n"
301 "smir %9,%pmc09\n"
302 "smir %10,%pmc10\n"
303 "smir %11,%pmc11\n"
304 "smir %12,%pmc12\n"
305 "smir %13,%pmc13\n"
306 "smir %14,%pmc14\n"
307 "smir %15,%pmc15\n"
308 :"=r"(pmc[0]),
309 "=r"(pmc[1]),
310 "=r"(pmc[2]),
311 "=r"(pmc[3]),
312 "=r"(pmc[4]),
313 "=r"(pmc[5]),
314 "=r"(pmc[6]),
315 "=r"(pmc[7]),
316 "=r"(pmc[8]),
317 "=r"(pmc[9]),
318 "=r"(pmc[10]),
319 "=r"(pmc[11]),
320 "=r"(pmc[12]),
321 "=r"(pmc[13]),
322 "=r"(pmc[14]),
323 "=r"(pmc[15])
324 :);
325
326 (void) flags;
327 (void) ctx;
329
330 long long curr_val = 0;
331
332 int c, i;
333 for( c = 0; c < control->active_counters; c++ ) {
334 i = control->which_counter[c];
335 curr_val = pmc[i];
336 SUBDBG("%d, current value %lld\n", i, curr_val);
337 control->count[c]=curr_val;
338 }
339
340 *events = ( ( _perfnec_control_state_t* ) ctl )->count;
341
342 return PAPI_OK;
343}
344
345#if defined(__crayxt)
346int _papi_hwd_start_create_context = 0; /* CrayPat checkpoint support */
347#endif /* XT */
348
349static int
351{
352 return PAPI_OK;
353}
354
355static int
357{
358 return PAPI_OK;
359}
360
361static inline int
363{
364 return PAPI_OK;
365}
366
367static int
369{
370 return ( PAPI_OK );
371}
372
373static int
375{
376 return ( PAPI_OK );
377}
378
379/* This will need to be modified for the Pentium IV */
380
381static inline int
382find_profile_index( EventSetInfo_t * ESI, int pmd, int *flags,
383 unsigned int *native_index, int *profile_index )
384{
385 return ( PAPI_OK );
386}
387
388#define BPL (sizeof(uint64_t)<<3)
389#define LBPL 6
390static inline void
391pfnec_bv_set( uint64_t * bv, uint16_t rnum )
392{
393}
394
395static inline int
396setup_ear_event( unsigned int native_index, pfarg_pmd_t * pd, int flags )
397{
398 return ( 0 );
399}
400
401static inline int
402process_smpl_entry( unsigned int native_pfnec_index, int flags,
403 pfnec_dfl_smpl_entry_t ** ent, vptr_t * pc )
404{
405
406 return 0;
407}
408
409static inline int
410process_smpl_buf( int num_smpl_pmds, int entry_size, ThreadInfo_t ** thr )
411{
412 return ( PAPI_OK );
413}
414
415
416/* This function used when hardware overflows ARE working
417 or when software overflows are forced */
418
419static void
421{
422}
423
424static int
426{
427 return ( PAPI_OK );
428}
429
430static int
432{
433 return ( PAPI_OK );
434}
435
436
437
438static int
440{
441 return ( PAPI_OK );
442}
443
444static int
446{
448 memset( control, 0, sizeof ( _perfnec_control_state_t ) );
449 return ( PAPI_OK );
450}
451
452static int
454{
455 return PAPI_OK;
456}
457
458/* This function clears the current contents of the control structure and
459 updates it with whatever resources are allocated for all the native events
460 in the native info structure array. */
461
462static int
465 hwd_context_t * ctx )
466{
467 (void) ctx;
468 int i, index;
469
471 control->active_counters = count;
472
473 for ( i = 0; i < count; ++i ) {
474 index = native[i].ni_event;
475 control->which_counter[i]=index;
476 native[i].ni_position = i;
477 }
478
479 return ( PAPI_OK );
480}
481
482static int
483_perfnec_ntv_enum_events( unsigned int *EventCode, int modifier )
484{
485 int index;
486 switch ( modifier ) {
487 case PAPI_ENUM_FIRST:
488 *EventCode = 0 | PAPI_NATIVE_MASK;
489 return PAPI_OK;
490 case PAPI_ENUM_EVENTS:
491 index = *EventCode & PAPI_NATIVE_AND_MASK;
492 if ( index < num_events - 1 ) {
493 *EventCode = (*EventCode + 1) | PAPI_NATIVE_MASK;
494 return PAPI_OK;
495 } else {
496 return PAPI_ENOEVNT;
497 }
498
499 default:
500 return PAPI_EINVAL;
501 }
502}
503
504/*
505 *
506 */
507static int
508_perfnec_ntv_code_to_name( unsigned int EventCode, char *name, int len )
509{
510 int index = EventCode & PAPI_NATIVE_AND_MASK;
511
512 if ( index >= 0 && index < num_events ) {
514 return PAPI_OK;
515 }
516
517 return PAPI_ENOEVNT;
518}
519
520static int
521_perfnec_ntv_code_to_info( unsigned int EventCode, PAPI_event_info_t *info )
522{
523 int index = EventCode & PAPI_NATIVE_AND_MASK;
524 if ( index < 0 || index >= num_events )
525 return PAPI_ENOEVNT;
526
527 _local_strlcpy( info->symbol, perfnec_ntv_events[index].name, sizeof( info->symbol ));
528 _local_strlcpy( info->units, perfnec_ntv_events[index].units, sizeof( info->units ) );
529 _local_strlcpy( info->long_descr, perfnec_ntv_events[index].description, sizeof( info->long_descr ) );
530
532
533 return PAPI_OK;
534}
535
536static int
537_perfnec_ntv_name_to_code( const char *name, unsigned int *EventCode)
538{
539 int i;
540 for (i = 0; i < PKG_NUM_EVENTS; ++i)
541 if (!strcmp(name, pkg_event_names[i])) {
542 *EventCode = i;
543 return PAPI_OK;
544 }
545 return PAPI_ENOEVNT;
546}
547
548
550 .cmp_info = {
551 /* default component information (unspecified values initialized to 0) */
552 .name = "perfnec",
553 .description = "Linux perfnec CPU counters for NEC architecture",
554 .version = "3.8",
555
556 .default_domain = PAPI_DOM_USER,
557 .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
558 .default_granularity = PAPI_GRN_THR,
559 .available_granularities = PAPI_GRN_THR,
560
561 .hardware_intr = 1,
562 .kernel_multiplex = 1,
563 .kernel_profile = 1,
564 .num_mpx_cntrs = PFNECLIB_MAX_PMDS,
565
566 /* component specific cmp_info initializations */
567 .fast_real_timer = 1,
568 .fast_virtual_timer = 0,
569 .attach = 1,
570 .attach_must_ptrace = 1,
571 },
572
573 /* sizes of framework-opaque component-private structures */
574 .size = {
575 .context = sizeof ( int ),//pfnec_context_t ),
576 .control_state = sizeof ( pfnec_control_state_t ),
577 .reg_value = sizeof ( int ), //pfnec_register_t ),
578 .reg_alloc = sizeof ( int ) //pfnec_reg_alloc_t ),
579 },
580 /* function pointers in this component */
581 .init_control_state = _papi_pfnec_init_control_state,
582 .start = _papi_pfnec_start,
583 .stop = _papi_pfnec_stop,
584 .read = _papi_pfnec_read,
585 .shutdown_thread = _papi_pfnec_shutdown,
586 .shutdown_component = _papi_pfnec_shutdown_component,
587 .ctl = _papi_pfnec_ctl,
588 .update_control_state = _papi_pfnec_update_control_state,
589 .set_domain = set_domain,
590 .reset = _papi_pfnec_reset,
591 .set_overflow = _papi_pfnec_set_overflow,
592 .set_profile = _papi_pfnec_set_profile,
593 .stop_profiling = _papi_pfnec_stop_profiling,
594 .init_component = _papi_pfnec_init_component,
595 .dispatch_timer = _papi_pfnec_dispatch_timer,
596 .init_thread = _papi_pfnec_init_thread,
597 .allocate_registers = _papi_pfnec_allocate_registers,
598 .write = _papi_pfnec_write,
599
600 /* from the counter name library */
601 .ntv_enum_events = _perfnec_ntv_enum_events,
602 .ntv_name_to_code = _perfnec_ntv_name_to_code,
603 .ntv_code_to_name = _perfnec_ntv_code_to_name,
604 .ntv_code_to_info = _perfnec_ntv_code_to_info,
605 .ntv_code_to_descr = NULL,//_perfnec_ntv_code_to_descr,
606 .ntv_code_to_bits = NULL//_papi_libpfnec_ntv_code_to_bits,
607
608};
int i
static long count
#define PAPI_DOM_USER
Definition: f90papi.h:174
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_DOM_KERNEL
Definition: f90papi.h:254
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_ECMP
Definition: f90papi.h:214
#define PAPI_DATATYPE_INT64
Definition: f90papi.h:227
#define PAPI_GRN_THR
Definition: f90papi.h:265
char events[MAX_EVENTS][BUFSIZ]
static int threshold
void * thread(void *arg)
Definition: kufrin.c:38
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
static char * _local_strlcpy(char *dst, const char *src, size_t size)
Definition: linux-libmsr.c:233
#define PAPI_NATIVE_AND_MASK
#define PAPI_NATIVE_MASK
Return codes and api definitions.
void * vptr_t
Definition: papi.h:576
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
FILE * stderr
static int native
static int cidx
static void dump_smpl_hdr(pfnec_dfl_smpl_hdr_t *hdr)
static int _papi_pfnec_write(hwd_context_t *ctx, hwd_control_state_t *ctl, long long *from)
static int process_smpl_entry(unsigned int native_pfnec_index, int flags, pfnec_dfl_smpl_entry_t **ent, vptr_t *pc)
static int setup_ear_event(unsigned int native_index, pfarg_pmd_t *pd, int flags)
static void dump_pmd(pfnec_control_state_t *ctl)
static int set_domain(hwd_control_state_t *ctl, int domain)
static int _perfnec_ntv_name_to_code(const char *name, unsigned int *EventCode)
static int num_events
static int _papi_pfnec_init_thread(hwd_context_t *thr_ctx)
static int find_profile_index(EventSetInfo_t *ESI, int pmd, int *flags, unsigned int *native_index, int *profile_index)
static int attach(hwd_control_state_t *ctl, unsigned long tid)
static int _papi_pfnec_write_pmcs(pfnec_context_t *ctx, pfnec_control_state_t *ctl)
static int _papi_pfnec_read_pmds(pfnec_context_t *ctx, pfnec_control_state_t *ctl)
static void dump_pmc(pfnec_control_state_t *ctl)
static void dump_smpl(pfnec_dfl_smpl_entry_t *entry)
#define PFNECLIB_MAX_PMDS
static int detect_timeout_and_unavail_pmu_regs(pfneclib_regmask_t *r_pmcs, pfneclib_regmask_t *r_pmds, unsigned long *timeout_ns)
static int compute_kernel_args(hwd_control_state_t *ctl0)
pfnec_context_t cmp_context_t
static int set_granularity(hwd_control_state_t *this_state, int domain)
static int _papi_pfnec_stop_profiling(ThreadInfo_t *thread, EventSetInfo_t *ESI)
static int _papi_pfnec_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static void dump_setinfo(pfarg_setinfo_t *setinfo, int num_sets)
papi_vector_t _perfnec_vector
static int check_multiplex_timeout(int ctx_fd, unsigned long *timeout_ns)
static uint64_t diff56(uint64_t after, uint64_t before)
static int process_smpl_buf(int num_smpl_pmds, int entry_size, ThreadInfo_t **thr)
static int _papi_pfnec_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int set_inherit(int arg)
static void _papi_pfnec_dispatch_timer(int n, hwd_siginfo_t *info, void *uc)
static int _papi_pfnec_allocate_registers(EventSetInfo_t *ESI)
pfnec_control_state_t cmp_control_state_t
static int _papi_pfnec_set_overflow(EventSetInfo_t *ESI, int EventIndex, int threshold)
static int _papi_pfnec_write_pmds(pfnec_context_t *ctx, pfnec_control_state_t *ctl)
static int _papi_pfnec_set_profile(EventSetInfo_t *ESI, int EventIndex, int threshold)
static int _papi_pfnec_init_component(int cidx)
static int round_requested_ns(int ns)
static int _papi_pfnec_init_control_state(hwd_control_state_t *ctl)
static int _papi_pfnec_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
static void pfnec_bv_set(uint64_t *bv, uint16_t rnum)
static void dump_sets(pfarg_setdesc_t *set, int num_sets)
static int _papi_pfnec_stop(hwd_context_t *ctx0, hwd_control_state_t *ctl0)
static int _papi_pfnec_shutdown(hwd_context_t *ctx0)
static int detach(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _papi_pfnec_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
static void dump_smpl_arg(pfnec_dfl_smpl_arg_t *arg)
static int _perfnec_ntv_code_to_name(unsigned int EventCode, char *name, int len)
static int _perfnec_ntv_enum_events(unsigned int *EventCode, int modifier)
static int get_string_from_file(char *file, char *str, int len)
static int _perfnec_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
static int _papi_pfnec_start(hwd_context_t *ctx0, hwd_control_state_t *ctl0)
static uint64_t diff52(uint64_t after, uint64_t before)
static int check_pmmr(void)
static int _perfnec_pfnec_pmu_type
static int _papi_pfnec_shutdown_component()
int pfnec_dfl_smpl_entry_t
Definition: perfnec.h:54
#define PKG_NUM_EVENTS
Definition: perfnec.h:56
static _perfnec_native_event_entry_t perfnec_ntv_events[PKG_NUM_EVENTS]
Definition: perfnec.h:103
static const char * pkg_event_descs[PKG_NUM_EVENTS]
Definition: perfnec.h:69
static int pkg_events[PKG_NUM_EVENTS]
Definition: perfnec.h:59
int pfnec_dfl_smpl_arg_t
Definition: perfnec.h:50
static const char * pkg_units[PKG_NUM_EVENTS]
Definition: perfnec.h:64
int pfneclib_regmask_t
Definition: perfnec.h:53
static const char * pkg_event_names[PKG_NUM_EVENTS]
Definition: perfnec.h:61
int pfnec_dfl_smpl_hdr_t
Definition: perfnec.h:51
char units[MAX_EVENTS][BUFSIZ]
Definition: powercap_plot.c:15
const char FILE * file
Definition: pscanf.h:13
const char * name
Definition: rocs.c:225
int
Definition: sde_internal.h:89
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:627
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:969
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:960
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
char units[PAPI_MIN_STR_LEN]
Definition: perfnec.h:93
int return_type
Definition: perfnec.h:99
_perfnec_register_t resources
Definition: perfnec.h:100
char name[PAPI_MAX_STR_LEN]
Definition: perfnec.h:92
int type
Definition: perfnec.h:98
char description[PAPI_MAX_STR_LEN]
Definition: perfnec.h:94
unsigned int selector
Definition: perfnec.h:88
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
long long count[PFNECLIB_MAX_PMDS]
Definition: perfnec.h:127
long long which_counter[PKG_NUM_EVENTS]
Definition: perfnec.h:129