26 #include "perfmon/pfmlib.h" 27 #include "perfmon/pfmlib_perf_event.h" 29 #define NATIVE_EVENT_CHUNK 1024 57 SUBDBG(
"Found allocated_name: %s, libpfm4_idx: %#x, papi_event_code: %#x\n",
70 SUBDBG(
"Found base_name: %s, mask_string: %s, libpfm4_idx: %#x, papi_event_code: %#x\n",
79 SUBDBG(
"EXIT: returned: %#x\n", event);
85 SUBDBG(
"ENTER: pinfo: %s %p, pinfo->is_present: %d, " 86 "pinfo->type: %#x, type: %#x\n",
87 pinfo->name, pinfo, pinfo->is_present, pinfo->type, type);
88 if (!pinfo->is_present) {
97 if ((pinfo->type==PFM_PMU_TYPE_CORE) && (type&
PMU_TYPE_CORE)) {
101 if ((pinfo->type==PFM_PMU_TYPE_OS_GENERIC) && (type&
PMU_TYPE_OS)) {
129 int libpfm4_index,
int cidx,
132 SUBDBG(
"ENTER: name: %s, libpfm4_index: %#x, event_table: %p, " 133 "event_table->pmu_type: %d\n",
134 name, libpfm4_index, event_table, event_table->
pmu_type);
141 char *event_string=NULL;
145 char fullname[BUFSIZ];
148 pfm_perf_encode_arg_t perf_arg;
149 pfm_event_info_t einfo;
150 pfm_event_attr_info_t ainfo;
151 pfm_pmu_info_t pinfo;
155 SUBDBG(
"EXIT: no place to put native events\n");
168 if (event_num >= 0) {
169 nevt_idx = event_num;
179 SUBDBG(
"event_num: %d, nevt_idx: %d, ntv_evt: %p\n",
180 event_num, nevt_idx, ntv_evt);
183 memset(&perf_arg,0,
sizeof(pfm_perf_encode_arg_t));
188 perf_arg.attr=&ntv_evt->
attr;
189 perf_arg.fstr=&event_string;
193 ret = pfm_get_os_event_encoding(
name,
195 PFM_OS_PERF_EVENT_EXT,
199 if ((
ret != PFM_SUCCESS) || (event_string == NULL)) {
200 SUBDBG(
"encode failed for event: %s, returned: %d\n",
215 ntv_evt->
attr.config = 0xFFFFFF;
226 event_string = strdup(
name);
228 SUBDBG(
"event_string: %s\n", event_string);
232 event = strstr (event_string,
"::");
236 pmu_name = strdup(event_string);
239 pmu_name = malloc(2);
241 event = event_string;
243 masks = strstr (event,
":");
252 if (strlen(pmu_name) == 0) {
253 sprintf(fullname,
"%s", event);
255 sprintf(fullname,
"%s::%s", pmu_name, event);
258 SUBDBG(
"pmu_name: %s, event: %s, masks: %s, fullname: %s\n",
259 pmu_name, event, masks, fullname);
265 if (libpfm4_index == -1) {
266 libpfm4_index = pfm_find_event(fullname);
267 if (libpfm4_index < 0) {
271 SUBDBG(
"EXIT: error from libpfm4 find event\n");
274 SUBDBG(
"libpfm4_index: %#x\n", libpfm4_index);
279 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
280 einfo.size =
sizeof(pfm_event_info_t);
281 if ((
ret = pfm_get_event_info(libpfm4_index,
282 PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
286 SUBDBG(
"EXIT: pfm_get_event_info failed with %d\n",
ret);
292 memset(&pinfo,0,
sizeof(pfm_pmu_info_t));
293 pinfo.size =
sizeof(pfm_pmu_info_t);
294 pfm_get_pmu_info(einfo.pmu, &pinfo);
299 SUBDBG(
"EXIT: PMU not supported by this component: einfo.pmu: %d, PFM_PMU_TYPE_CORE: %d\n", einfo.pmu, PFM_PMU_TYPE_CORE);
306 ntv_evt->
pmu=pmu_name;
312 ntv_evt->
cpu=perf_arg.cpu;
314 SUBDBG(
"ntv_evt->mask_string: %p (%s)\n",
316 char *msk_ptr = strdup(masks);
322 if ((msk_ptr != NULL) && (strlen(msk_ptr) > 0)) {
326 SUBDBG(
"ptr: %p (%s)\n", ptr, ptr);
327 while (ptr != NULL) {
328 char *ptrm = strstr(ptr,
":");
335 char *wrk = strchr(ptr,
'=');
336 unsigned int msk_name_len;
338 msk_name_len = wrk - ptr;
339 SUBDBG(
"Found =, length=%d\n",msk_name_len);
341 msk_name_len = strlen (ptr);
342 SUBDBG(
"No =, length=%d\n",msk_name_len);
346 for (
i=0 ;
i<einfo.nattrs ;
i++) {
351 sizeof(pfm_event_attr_info_t));
352 ainfo.size =
sizeof(pfm_event_attr_info_t);
353 ret = pfm_get_event_attr_info(libpfm4_index,
354 i, PFM_OS_PERF_EVENT_EXT, &ainfo);
355 if (
ret != PFM_SUCCESS) {
364 if ((msk_name_len == strlen(ainfo.name)) &&
365 (strncmp(ptr, ainfo.name, msk_name_len) == 0)) {
367 SUBDBG(
"Found mask: libpfm4=%s -- matches %s -- i: %d, %d %zu\n",
368 ainfo.name, ptr,
i, msk_name_len, strlen(ainfo.name));
370 unsigned int mskleft =
sizeof(mask_desc) - strlen(mask_desc);
373 SUBDBG(
"EXIT: Attribute description discarded: %s\n", ainfo.desc);
377 if (strlen(mask_desc) > 0) {
378 strcat (mask_desc,
":");
382 if (mskleft < (strlen(ainfo.desc) + 1)) {
383 SUBDBG(
"EXIT: Attribute description truncated: %s\n", ainfo.desc);
386 strncat (mask_desc, ainfo.desc, mskleft-1);
387 mask_desc[mskleft-1] =
'\0';
394 SUBDBG(
"Mask not found! %s\n",ptr);
400 if ( (
sizeof(mask_desc) - strlen(mask_desc)) <= 1) {
410 if (msk_ptr != NULL) {
423 SUBDBG(
"Native Event: papi_event_code: %#x, libpfm4_idx: %#x, pmu: %s, base_name: %s, mask_string: %s, allocated_name: %s\n",
425 SUBDBG(
"event_table->native_events[%d]: %p, cpu: %d, attr.config: 0x%"PRIx64
", attr.config1: 0x%"PRIx64
", attr.config2: 0x%"PRIx64
", attr.type: 0x%"PRIx32
", attr.exclude_user: %d, attr.exclude_kernel: %d, attr.exclude_guest: %d\n",
427 ntv_evt->
attr.config1, ntv_evt->
attr.config2, ntv_evt->
attr.type,
428 ntv_evt->
attr.exclude_user, ntv_evt->
attr.exclude_kernel, ntv_evt->
attr.exclude_guest);
435 SUBDBG(
"Allocating more room for native events (%d %ld)\n",
455 SUBDBG(
"EXIT: attempt to get more space for " 456 "native events failed\n");
467 if (encode_failed != 0) {
468 SUBDBG(
"EXIT: encoding event failed\n");
472 SUBDBG(
"EXIT: new_event: %p\n", ntv_evt);
488 SUBDBG(
"ENTER: pmu_idx: %d, pmu_type: %d\n", pmu_idx, pmu_type);
491 pfm_pmu_info_t pinfo;
503 memset(&pinfo,0,
sizeof(pfm_pmu_info_t));
504 pinfo.size =
sizeof(pfm_pmu_info_t);
505 ret=pfm_get_pmu_info(pmu_idx, &pinfo);
507 if (
ret==PFM_ERR_INVAL) {
513 pidx=pinfo.first_event;
514 SUBDBG(
"First event in pmu: %s is %#x\n", pinfo.name, pidx);
523 SUBDBG(
"EXIT: pidx: %#x\n", pidx);
532 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
563 SUBDBG(
"ENTER: name: %s, event_code: %p, *event_code: %#x, event_table: %p\n",
name, event_code, *event_code, event_table);
570 if (event_num >= 0) {
580 if (our_event==NULL) {
581 SUBDBG(
"EXIT: Allocating event: '%s' failed\n",
name);
586 SUBDBG(
"EXIT: Found code: %#x\n",*event_code);
610 char *ntv_name,
int len,
613 SUBDBG(
"ENTER: EventCode: %#x, ntv_name: %p, len: %d, event_table: %p\n", EventCode, ntv_name, len, event_table);
623 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
643 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
657 if (strlen (ename) >= (
unsigned)len) {
658 SUBDBG(
"EXIT: event name %s will not fit in buffer provided\n", ename);
661 strcpy (ntv_name, ename);
665 if ((mname != NULL) && (strlen(mname) > 0)) {
666 if ((strlen(ename) + 8 + strlen(mname)) >= (
unsigned)len) {
667 SUBDBG(
"EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (
unsigned)(strlen(ename) + 8 + strlen(mname)), (
unsigned)len);
670 strcat (ntv_name,
":");
671 strcat (ntv_name, mname);
674 SUBDBG(
"EXIT: event name: %s\n", ntv_name);
703 char *ntv_descr,
int len,
706 SUBDBG(
"ENTER: EventCode: %#x, ntv_descr: %p, len: %d: event_table: %p\n", EventCode, ntv_descr, len, event_table);
718 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
738 SUBDBG(
"EXIT: PAPI_ENOEVNT\n");
745 if (strlen (edesc) >= (
unsigned)len) {
746 SUBDBG(
"EXIT: event name %s will not fit in buffer provided\n", edesc);
749 strcpy (ntv_descr, edesc);
753 if ((mdesc != NULL) && (strlen(mdesc) > 0)) {
754 if ((strlen(edesc) + 8 + strlen(mdesc)) >= (
unsigned)len) {
755 SUBDBG(
"EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (
unsigned)(strlen(edesc) + 8 + strlen(mdesc)), (
unsigned)len);
758 strcat (ntv_descr,
", masks:");
759 strcat (ntv_descr, mdesc);
762 SUBDBG(
"EXIT: event description: %s\n", ntv_descr);
772 SUBDBG(
"ENTER: EventCode: %#x, info: %p, event_table: %p\n", EventCode, info, event_table);
778 SUBDBG(
"EXIT: _pe_libpfm4_ntv_code_to_name returned: %d\n",
ret);
783 SUBDBG(
"EXIT: _pe_libpfm4_ntv_code_to_descr returned: %d\n",
ret);
810 int modifier,
int cidx,
813 SUBDBG(
"ENTER: PapiEventCode: %p, *PapiEventCode: %#x, modifier: %d, event_table: %p\n", PapiEventCode, *PapiEventCode, modifier, event_table);
817 char event_string[BUFSIZ];
818 pfm_pmu_info_t pinfo;
819 pfm_event_info_t einfo;
827 SUBDBG(
"EXIT: Invalid component first event code: %d\n", code);
832 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
833 einfo.size =
sizeof(pfm_event_info_t);
834 if ((
ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
835 SUBDBG(
"EXIT: pfm_get_event_info returned: %d\n",
ret);
840 memset( &pinfo, 0,
sizeof(pfm_pmu_info_t) );
841 pinfo.size =
sizeof(pfm_pmu_info_t);
842 ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
843 if (
ret!=PFM_SUCCESS) {
844 SUBDBG(
"EXIT: pfm_get_pmu_info returned: %d\n",
ret);
849 sprintf (event_string,
"%s::%s", pinfo.name, einfo.name);
850 SUBDBG(
"code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
859 SUBDBG(
"EXIT: Allocating event: '%s' failed\n", event_string);
865 SUBDBG(
"EXIT: event code: %#x\n", *PapiEventCode);
871 SUBDBG(
"EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
880 if ((code = pfm_get_event_next(*PapiEventCode)) < 0) {
883 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
884 einfo.size =
sizeof(pfm_event_info_t);
885 if ((
ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
886 SUBDBG(
"EXIT: pfm_get_event_info returned: %d\n",
ret);
889 SUBDBG(
"*PapiEventCode: %#x, event: %s\n", *PapiEventCode, einfo.name);
894 SUBDBG(
"pnum: %d\n", pnum);
897 SUBDBG(
"EXIT: No more PMUs to list, returning: %d\n", code);
904 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
905 einfo.size =
sizeof(pfm_event_info_t);
906 if ((
ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
907 SUBDBG(
"EXIT: pfm_get_event_info returned: %d\n",
ret);
912 memset( &pinfo, 0,
sizeof(pfm_pmu_info_t) );
913 pinfo.size =
sizeof(pfm_pmu_info_t);
914 ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
915 if (
ret!=PFM_SUCCESS) {
916 SUBDBG(
"EXIT: pfm_get_pmu_info returned: %d\n",
ret);
921 sprintf (event_string,
"%s::%s", pinfo.name, einfo.name);
922 SUBDBG(
"code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
931 SUBDBG(
"EXIT: Allocating event: '%s' failed\n", event_string);
937 SUBDBG(
"EXIT: event code: %#x\n", *PapiEventCode);
944 SUBDBG(
"EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
950 SUBDBG(
"EXIT: do not support umask combos yet\n");
957 memset( &einfo, 0,
sizeof( pfm_event_info_t ));
958 einfo.size =
sizeof(pfm_event_info_t);
959 if ((
ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
960 SUBDBG(
"EXIT: pfm_get_event_info returned: %d\n",
ret);
966 max_umasks = einfo.nattrs;
970 SUBDBG(
"EXIT: already processed all umasks: attr_idx: %d\n",
attr_idx);
977 SUBDBG(
"EXIT: _papi_hwi_get_ntv_idx returned: %d\n", ntv_idx);
981 if ((ename == NULL) || (strlen(ename) >=
sizeof(event_string))) {
982 SUBDBG(
"EXIT: Event name will not fit into buffer\n");
985 strcpy (event_string, ename);
986 SUBDBG(
"event_string: %s\n", event_string);
990 pfm_event_attr_info_t ainfo;
991 memset (&ainfo, 0,
sizeof(pfm_event_attr_info_t));
992 ainfo.size =
sizeof(pfm_event_attr_info_t);
993 ret = pfm_get_event_attr_info(*PapiEventCode,
attr_idx, PFM_OS_PERF_EVENT_EXT, &ainfo);
994 if (
ret != PFM_SUCCESS) {
998 SUBDBG(
"*PapiEventCode: %#x, attr_idx: %d, type: %d, name: %s, description: %s\n", *PapiEventCode,
attr_idx, ainfo.type, ainfo.name, ainfo.desc);
1000 if (strlen(event_string) + strlen(ainfo.name) + 35 >
sizeof(event_string)) {
1001 SUBDBG(
"EXIT: Event name and mask will not fit into buffer\n");
1005 strcat (event_string,
":");
1006 strcat (event_string, ainfo.name);
1007 switch (ainfo.type) {
1008 case PFM_ATTR_UMASK:
1010 case PFM_ATTR_MOD_BOOL:
1011 case PFM_ATTR_MOD_INTEGER:
1013 strcat(event_string,
"=0");
1016 SUBDBG(
"EXIT: Unsupported attribute type: %d", ainfo.type);
1027 SUBDBG(
"EXIT: Allocating event: '%s' failed\n", event_string);
1034 SUBDBG(
"EXIT: event code: %#x\n", *PapiEventCode);
1044 SUBDBG(
"EXIT: event code: %#x\n", *PapiEventCode);
1050 SUBDBG(
"EXIT: do not support enumerating groups in this component\n");
1056 SUBDBG(
"EXIT: Invalid modifier argument provided\n");
1074 SUBDBG(
"ENTER: event_table: %p\n", event_table);
1104 SUBDBG(
"EXIT: PAPI_OK\n");
1127 int detected_pmus=0, found_default=0;
1132 pfm_err_t
retval = PFM_SUCCESS;
1133 pfm_pmu_info_t pinfo;
1142 strncpy(
component->cmp_info.disabled_reason,
1155 memset(&(event_table->
default_pmu), 0,
sizeof(pfm_pmu_info_t));
1156 event_table->
default_pmu.size =
sizeof(pfm_pmu_info_t);
1159 SUBDBG(
"Detected pmus:\n");
1162 memset(&pinfo,0,
sizeof(pfm_pmu_info_t));
1163 pinfo.size =
sizeof(pfm_pmu_info_t);
1164 retval=pfm_get_pmu_info(
i, &pinfo);
1170 if (
retval==PFM_ERR_INVAL) {
1174 if ((
retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1178 pinfo.name,pinfo.desc,pinfo.type);
1181 ncnt+=pinfo.nevents;
1191 if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
1192 strcmp(pinfo.name,
"ix86arch")) {
1194 SUBDBG(
"\t %s is default\n",pinfo.name);
1196 &pinfo,
sizeof(pfm_pmu_info_t));
1208 SUBDBG(
"%d native events detected on %d pmus\n",ncnt,detected_pmus);
1210 if (detected_pmus==0) {
1211 SUBDBG(
"Could not find any PMUs\n");
1215 if (!found_default) {
1216 strncpy(
component->cmp_info.disabled_reason,
1221 if (found_default>1) {
1222 strncpy(
component->cmp_info.disabled_reason,
1227 component->cmp_info.num_native_events = ncnt;
1235 if ((
cidx==0) && (found_default)) {
1263 int detected_pmus=0;
1266 pfm_err_t
retval = PFM_SUCCESS;
1268 pfm_pmu_info_t pinfo;
1290 SUBDBG(
"Detected pmus:\n");
1293 memset(&pinfo,0,
sizeof(pfm_pmu_info_t));
1294 pinfo.size =
sizeof(pfm_pmu_info_t);
1295 retval=pfm_get_pmu_info(
i, &pinfo);
1301 if (
retval==PFM_ERR_INVAL) {
1305 if ((
retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1308 SUBDBG(
"\t%d %s %s %d\n",
i,pinfo.name,pinfo.desc,pinfo.type);
1311 ncnt+=pinfo.nevents;
1317 pinfo.num_fixed_cntrs;
1321 SUBDBG(
"%d native events detected on %d pmus\n",ncnt,detected_pmus);
static int get_first_event_next_pmu(int pmu_idx, int pmu_type)
int _papi_hwi_get_ntv_idx(unsigned int papi_evt_code)
static unsigned int papi_event_code
unsigned int _papi_hwi_get_papi_event_code()
int allocated_native_events
struct native_event_t * native_events
#define NATIVE_EVENT_CHUNK
int _pe_libpfm4_ntv_enum_events(unsigned int *PapiEventCode, int modifier, int cidx, struct native_event_table_t *event_table)
int _pe_libpfm4_ntv_name_to_code(const char *name, unsigned int *event_code, int cidx, struct native_event_table_t *event_table)
char long_descr[PAPI_HUGE_STR_LEN]
static int find_existing_event(const char *name, struct native_event_table_t *event_table)
PAPI_component_info_t cmp_info
int _papi_libpfm4_error(int pfm_error)
Return codes and api definitions.
int _pe_libpfm4_init(papi_vector_t *component, int cidx, struct native_event_table_t *event_table, int pmu_type)
int _pe_libpfm4_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len, struct native_event_table_t *event_table)
inline_static int _papi_hwi_lock(int lck)
int _papi_hwi_native_to_eventcode(int cidx, int event_code, int ntv_idx, const char *event_name)
char symbol[PAPI_HUGE_STR_LEN]
#define PAPI_HUGE_STR_LEN
inline_static int _papi_hwi_unlock(int lck)
#define SUBDBG(format, args...)
int _papi_load_preset_table(char *pmu_str, int pmu_type, int cidx)
int _peu_libpfm4_init(papi_vector_t *my_vector, int cidx, struct native_event_table_t *event_table, int pmu_type)
static struct native_event_t * allocate_native_event(const char *name, int libpfm4_index, int cidx, struct native_event_table_t *event_table)
int _pe_libpfm4_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info, struct native_event_table_t *event_table)
int _pe_libpfm4_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len, struct native_event_table_t *event_table)
static int pmu_is_present_and_right_type(pfm_pmu_info_t *pinfo, int type)
void _papi_hwi_set_papi_event_code(unsigned int event_code, int update_flag)
int _pe_libpfm4_shutdown(papi_vector_t *my_vector, struct native_event_table_t *event_table)
pfm_pmu_info_t default_pmu
char * pmu_names[PAPI_PMU_MAX]
void _papi_hwi_set_papi_event_string(const char *event_string)