PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux-sensors-ppc.c File Reference
Include dependency graph for linux-sensors-ppc.c:

Go to the source code of this file.

Macros

#define HANDLE_STRING_ERROR   {fprintf(stderr,"%s:%i unexpected string function error.\n",__FILE__,__LINE__); exit(-1);}
 
#define DESC_LINE_SIZE_ALLOWED   66
 
#define TO_FP(f)   ((f >> 8) * _pow(10, ((int8_t)(f & 0xFF))))
 

Functions

static char * _local_strlcpy (char *dst, const char *src, size_t size)
 
static void _space_padding (char *buf, size_t max)
 
static void refresh_data (int occ_id, int forced)
 Refresh_data locks in write and update ping and pong at the same time for OCC occ_id. The occ_names array contains constant memory and doesn't need to be updated. Ping and Pong are read outside of the critical path, and only the swap needs to be protected.
 
static double _pow (int x, int y)
 
static long long read_sensors_ppc_record (int s, int gidx, int midx)
 
static long long read_sensors_ppc_counter (int s, int gidx)
 
static int _sensors_ppc_is_counter (int index)
 
static long long read_sensors_ppc_value (int index)
 
static int _sensors_ppc_init_thread (hwd_context_t *ctx)
 
static int _sensors_ppc_init_component (int cidx)
 
static int _sensors_ppc_init_control_state (hwd_control_state_t *ctl)
 
static int _sensors_ppc_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _sensors_ppc_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _sensors_ppc_shutdown_thread (hwd_context_t *ctx)
 
static int _sensors_ppc_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
 
static int _sensors_ppc_shutdown_component (void)
 
static int _sensors_ppc_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
 
static int _sensors_ppc_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
 
static int _sensors_ppc_set_domain (hwd_control_state_t *ctl, int domain)
 
static int _sensors_ppc_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _sensors_ppc_ntv_enum_events (unsigned int *EventCode, int modifier)
 
static int _sensors_ppc_ntv_code_to_name (unsigned int EventCode, char *name, int len)
 
static int _sensors_ppc_ntv_code_to_info (unsigned int EventCode, PAPI_event_info_t *info)
 

Variables

papi_vector_t _sensors_ppc_vector
 

Macro Definition Documentation

◆ DESC_LINE_SIZE_ALLOWED

#define DESC_LINE_SIZE_ALLOWED   66

Definition at line 47 of file linux-sensors-ppc.c.

◆ HANDLE_STRING_ERROR

#define HANDLE_STRING_ERROR   {fprintf(stderr,"%s:%i unexpected string function error.\n",__FILE__,__LINE__); exit(-1);}

Definition at line 29 of file linux-sensors-ppc.c.

◆ TO_FP

#define TO_FP (   f)    ((f >> 8) * _pow(10, ((int8_t)(f & 0xFF))))

Definition at line 109 of file linux-sensors-ppc.c.

Function Documentation

◆ _local_strlcpy()

static char * _local_strlcpy ( char *  dst,
const char *  src,
size_t  size 
)
static

Definition at line 39 of file linux-sensors-ppc.c.

40{
41 char *retval = strncpy( dst, src, size );
42 if ( size > 0 ) dst[size-1] = '\0';
43
44 return( retval );
45}
int retval
Definition: zero_fork.c:53
Here is the caller graph for this function:

◆ _pow()

static double _pow ( int  x,
int  y 
)
static

Definition at line 99 of file linux-sensors-ppc.c.

100{
101 if (0 == y) return 1.;
102 if (0 == x) return 0.;
103 if (0 > y) return 1. / _pow(x, -y);
104 if (1 == y) return 1. * x;
105 if (0 == y%2) return _pow(x, y/2) * _pow(x, y/2);
106 else return _pow(x, y/2) * _pow(x, y/2) * x;
107}
static double _pow(int x, int y)
volatile double y
volatile double x
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _sensors_ppc_ctl()

static int _sensors_ppc_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)
static

Definition at line 515 of file linux-sensors-ppc.c.

516{
517 SUBDBG( "Enter: ctx: %p\n", ctx );
518 (void) ctx;
519 (void) code;
520 (void) option;
521
522 return PAPI_OK;
523}
#define PAPI_OK
Definition: f90papi.h:73
#define SUBDBG(format, args...)
Definition: papi_debug.h:64

◆ _sensors_ppc_init_component()

static int _sensors_ppc_init_component ( int  cidx)
static

Definition at line 244 of file linux-sensors-ppc.c.

245{
246 int retval = PAPI_OK;
247 int s = -1;
248 int strErr;
249 char events_dir[128];
250 char event_path[128];
251 char *strCpy;
252 DIR *events;
253
254 const PAPI_hw_info_t *hw_info;
256
257 if ( PAPI_VENDOR_IBM != hw_info->vendor ) {
258 strCpy=strncpy(_sensors_ppc_vector.cmp_info.disabled_reason, "Not an IBM processor", PAPI_MAX_STR_LEN);
260 if (strCpy == NULL) HANDLE_STRING_ERROR;
262 goto fn_fail;
263 }
264
265 int ret = snprintf(events_dir, sizeof(events_dir), "/sys/firmware/opal/exports/");
266 if (ret <= 0 || (int)(sizeof(events_dir)) <= ret) HANDLE_STRING_ERROR;
267 if (NULL == (events = opendir(events_dir))) {
269 "%s:%i Could not open events_dir='%s'.", __FILE__, __LINE__, events_dir);
273 goto fn_fail;
274 }
275
276 ret = snprintf(event_path, sizeof(event_path), "%s%s", events_dir, pkg_sys_name);
277 if (ret <= 0 || (int)(sizeof(event_path)) <= ret) HANDLE_STRING_ERROR;
278 if (-1 == access(event_path, F_OK)) {
280 "%s:%i Could not access event_path='%s'.", __FILE__, __LINE__, event_path);
284 goto fn_fail;
285 }
286
287 event_fd = open(event_path, pkg_sys_flag);
288 if (event_fd < 0) {
290 "%s:%i Could not open event_path='%s'.", __FILE__, __LINE__, event_path);
294 goto fn_fail;
295 }
296
297 memset(occ_num_events, 0, (MAX_OCCS+1)*sizeof(int));
298 num_events = 0;
299 for ( s = 0; s < MAX_OCCS; ++s ) {
300 void *buf = NULL;
301 if (NULL == (buf = malloc(OCC_SENSOR_DATA_BLOCK_SIZE))) {
303 "%s:%i Failed to alloc %i bytes for buf.", __FILE__, __LINE__, OCC_SENSOR_DATA_BLOCK_SIZE);
307 goto fn_fail;
308 }
309
311
313
314 int rc, bytes;
315 /* copy memory iteratively until the full chunk is saved */
316 for (rc = bytes = 0; bytes < OCC_SENSOR_DATA_BLOCK_SIZE; bytes += rc) {
317 rc = read(event_fd, buf + bytes, OCC_SENSOR_DATA_BLOCK_SIZE - bytes);
318 if (!rc || rc < 0) /* done */ break;
319 }
320
321 if (OCC_SENSOR_DATA_BLOCK_SIZE != bytes) {
322 /* We are running out of OCCs, let's stop there */
323 free(buf);
324 num_occs = s;
325 s = MAX_OCCS;
326 continue;
327 }
328
329 occ_sensor_name_t *names = (occ_sensor_name_t*)((uint64_t)buf + be32toh(occ_hdr[s]->names_offset));
330 int n_sensors = be16toh(occ_hdr[s]->nr_sensors);
331
332 /* Prepare the double buffering for the ping/pong buffers */
333 int ping_off = be32toh(occ_hdr[s]->reading_ping_offset);
334 int pong_off = be32toh(occ_hdr[s]->reading_pong_offset);
335 /* Ping and pong are both 40kB, and we have a 4kB separator.
336 * In theory, the distance between the beginnings of ping and pong is (40+4) kB.
337 * But they expose an offset for the pong buffer.
338 * So I won't trust the 4kB distance between buffers, and compute the buffer size
339 * based on on both offsets ans the size of pong */
340 int buff_size = pong_off - ping_off + OCC_PING_DATA_BLOCK_SIZE;
341
342 ping[s] = (uint32_t*)malloc(buff_size);
343 if (ping[s] == NULL) {
345 "%s:%i Failed to alloc %i bytes for ping[%i].", __FILE__, __LINE__, buff_size, s);
349 goto fn_fail;
350 }
351
352 double_ping[s] = (uint32_t*)malloc(buff_size);
353 if (double_ping[s] == NULL) {
355 "%s:%i Failed to alloc %i bytes for double_ping[%i].", __FILE__, __LINE__, buff_size, s);
359 goto fn_fail;
360 }
361
363
364 refresh_data(s, 1);
365
366 /* Not all events will exist, counter-based evens only have an accumulator to report */
367 occ_num_events[s+1] = occ_num_events[s] + (n_sensors * OCC_SENSORS_MASKS);
368
369 num_events += (n_sensors * OCC_SENSORS_MASKS);
370
371 /* occ_names map to read-only information that change only after reboot */
372 occ_names[s] = names;
373 }
374
375 /* Export the total number of events available */
379
380 /* 0 active events */
381 num_events = 0;
382
383 /* Export the component id */
385
386 fn_exit:
387 _papi_hwd[cidx]->cmp_info.disabled = retval;
388 return retval;
389 fn_fail:
390 goto fn_exit;
391}
int open(const char *pathname, int flags, mode_t mode)
Definition: appio.c:188
off_t lseek(int fd, off_t offset, int whence)
Definition: appio.c:214
ssize_t read(int fd, void *buf, size_t count)
Definition: appio.c:229
const char * names[NUM_EVENTS]
static const PAPI_hw_info_t * hw_info
Definition: byte_profile.c:28
double s
Definition: byte_profile.c:36
struct papi_vectors * _papi_hwd[]
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
Definition: do_loops.c:12
#define PAPI_VENDOR_IBM
Definition: f90papi.h:61
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_ENOMEM
Definition: f90papi.h:16
char events[MAX_EVENTS][BUFSIZ]
static int num_events
static void refresh_data(int occ_id, int forced)
Refresh_data locks in write and update ping and pong at the same time for OCC occ_id....
papi_vector_t _sensors_ppc_vector
#define HANDLE_STRING_ERROR
static char * pkg_sys_name
#define MAX_OCCS
#define OCC_SENSOR_DATA_BLOCK_SIZE
uint16_t nr_sensors
uint32_t reading_pong_offset
static mode_t pkg_sys_flag
struct occ_sensor_data_header_s * occ_hdr[MAX_OCCS]
static int num_occs
uint32_t names_offset
uint32_t reading_ping_offset
static uint32_t * double_pong[MAX_OCCS]
#define OCC_PING_DATA_BLOCK_SIZE
@ OCC_SENSORS_MASKS
static int occ_num_events[MAX_OCCS+1]
static int event_fd
struct occ_sensor_name_s * occ_names[MAX_OCCS]
static uint32_t * ping[MAX_OCCS]
static uint32_t * double_ping[MAX_OCCS]
static int cidx
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:56
rc
Definition: pscanf.h:23
char disabled_reason[PAPI_HUGE_STR_LEN]
Definition: papi.h:634
Hardware info structure.
Definition: papi.h:774
int vendor
Definition: papi.h:781
PAPI_hw_info_t hw_info
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
Here is the call graph for this function:

◆ _sensors_ppc_init_control_state()

static int _sensors_ppc_init_control_state ( hwd_control_state_t ctl)
static

Definition at line 399 of file linux-sensors-ppc.c.

400{
402
403 memset( control, 0, sizeof ( _sensors_ppc_control_state_t ) );
404
405 return PAPI_OK;
406}

◆ _sensors_ppc_init_thread()

static int _sensors_ppc_init_thread ( hwd_context_t ctx)
static

Definition at line 233 of file linux-sensors-ppc.c.

234{
235 (void) ctx;
236
237 return PAPI_OK;
238}

◆ _sensors_ppc_is_counter()

static int _sensors_ppc_is_counter ( int  index)
static

Definition at line 190 of file linux-sensors-ppc.c.

191{
192 int s = 0;
193 /* get OCC s from index */
194 for (; index > occ_num_events[s+1] && s < MAX_OCCS; ++s);
195
196 int ridx = index - occ_num_events[s];
197 int gidx = ridx / OCC_SENSORS_MASKS;
199}
#define OCC_SENSOR_READING_COUNTER
uint8_t structure_type
Here is the caller graph for this function:

◆ _sensors_ppc_ntv_code_to_info()

static int _sensors_ppc_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
)
static

Definition at line 636 of file linux-sensors-ppc.c.

637{
638 int index = EventCode;
639
640 if ( index < 0 || index >= occ_num_events[num_occs])
641 return PAPI_ENOEVNT;
642
643 int s = 0;
644 /* get OCC s from index */
645 for (; index > occ_num_events[s+1] && s < MAX_OCCS; ++s);
646
647 int ridx = index - occ_num_events[s];
648 int gidx = ridx / OCC_SENSORS_MASKS;
649 int midx = ridx % OCC_SENSORS_MASKS;
650
651 /* EventCode maps to a counter */
652 /* Counters only expose their accumulator */
654 return PAPI_ENOEVNT;
655
656 char buf[512];
657 int ret = snprintf(buf, 512, "%s:occ=%d%s", occ_names[s][gidx].name, s, sensors_ppc_fake_qualifiers[midx]);
658 if (ret <= 0 || 512 <= ret)
659 return PAPI_ENOSUPP;
660 _local_strlcpy( info->symbol, buf, sizeof( info->symbol ));
661 _local_strlcpy( info->units, occ_names[s][gidx].units, sizeof( info->units ) );
662 /* If it ends with:
663 * Qw: w-th Quad unit [0-5]
664 * Cxx: xx-th core [0-23]
665 * My: y-th memory channel [0-8]
666 * CHvv: vv-th memory module [0-15]
667 * or starts with:
668 * GPUz: z-th GPU [0-2]
669 * TEMPGPUz: z-th GPU [0-2]
670 * */
671 uint16_t type = be16toh(occ_names[s][gidx].type);
672 char *name = strdup(occ_names[s][gidx].name);
673 uint32_t freq = be32toh(occ_names[s][gidx].freq);
674 int tgt = -1;
675 switch(type) {
676 /* IPS, STOPDEEPACTCxx, STOPDEEPREQCxx, IPSCxx, NOTBZECxx, NOTFINCxx,
677 * MRDMy, MWRMy, PROCPWRTHROT, PROCOTTHROT, MEMPWRTHROT, MEMOTTHROT,
678 * GPUzHWTHROT, GPUzSWTHROT, GPUzSWOTTHROT, GPUzSWPWRTHROT */
680 if (!strncmp(name, "GPU", 3)) {
681 char z[] = {name[3], '\0'};
682 tgt = atoi(z);
683 name[3] = 'z';
684 if (!strncmp(name, "GPUzHWTHROT", 11))
685 ret = snprintf(buf, 512, "Total time GPU %d has been throttled by hardware (thermal or power brake)", tgt);
686 else if (!strncmp(name, "GPUzSWTHROT", 11))
687 ret = snprintf(buf, 512, "Total time GPU %d has been throttled by software for any reason", tgt);
688 else if (!strncmp(name, "GPUzSWOTTHROT", 13))
689 ret = snprintf(buf, 512, "Total time GPU %d has been throttled by software due to thermal", tgt);
690 else if (!strncmp(name, "GPUzSWPWRTHROT", 14))
691 ret = snprintf(buf, 512, "Total time GPU %d has been throttled by software due to power", tgt);
692 else
693 ret = snprintf(buf, 512, "[PERFORMANCE] Unexpected: GPU-%d %s", tgt, name);
694 }
695 else if (!strncmp(name, "IPSCxx", 4)) {
696 tgt = atoi(name+4);
697 ret = snprintf(buf, 512, "Instructions per second for core %d on this Processor", tgt);
698 }
699 else if (!strncmp(name, "IPS", 3))
700 ret = snprintf(buf, 512, "Vector sensor that takes the average of all the cores this Processor");
701 else if (!strncmp(name, "STOPDEEPACTCxx", 12)) {
702 tgt = atoi(name+12);
703 ret = snprintf(buf, 512, "Deepest actual stop state that was fully entered during sample time for core %d", tgt);
704 }
705 else if (!strncmp(name, "STOPDEEPREQCxx", 12)) {
706 tgt = atoi(name+12);
707 ret = snprintf(buf, 512, "Deepest stop state that has been requested during sample time for core %d", tgt);
708 }
709 else if (!strncmp(name, "MEMPWRTHROT", 11))
710 ret = snprintf(buf, 512, "Count of memory throttled due to power");
711 else if (!strncmp(name, "MEMOTTHROT", 10))
712 ret = snprintf(buf, 512, "Count of memory throttled due to memory Over temperature");
713 else if (!strncmp(name, "PROCOTTHROT", 11))
714 ret = snprintf(buf, 512, "Count of processor throttled for temperature");
715 else if (!strncmp(name, "PROCPWRTHROT", 12))
716 ret = snprintf(buf, 512, "Count of processor throttled due to power");
717 else if (!strncmp(name, "MWRM", 4)) {
718 tgt = atoi(name+4);
719 ret = snprintf(buf, 512, "Memory write requests per sec for MC %d", tgt);
720 }
721 else if (!strncmp(name, "MRDM", 4)) {
722 tgt = atoi(name+4);
723 ret = snprintf(buf, 512, "Memory read requests per sec for MC %d", tgt);
724 }
725 else
726 ret = snprintf(buf, 512, "[PERFORMANCE] Unexpected: %s", name);
727 break;
728
729 /* PWRSYS, PWRGPU, PWRAPSSCHvv, PWRPROC, PWRVDD, PWRVDN, PWRMEM */
731 if (!strncmp(name, "PWRSYS", 6))
732 ret = snprintf(buf, 512, "Bulk power of the system/node");
733 else if (!strncmp(name, "PWRGPU", 6))
734 ret = snprintf(buf, 512, "Power consumption for GPUs per socket (OCC) read from APSS");
735 else if (!strncmp(name, "PWRPROC", 7))
736 ret = snprintf(buf, 512, "Power consumption for this Processor");
737 else if (!strncmp(name, "PWRVDD", 6))
738 ret = snprintf(buf, 512, "Power consumption for this Processor's Vdd (calculated from AVSBus readings)");
739 else if (!strncmp(name, "PWRVDN", 6))
740 ret = snprintf(buf, 512, "Power consumption for this Processor's Vdn (nest) (calculated from AVSBus readings)");
741 else if (!strncmp(name, "PWRMEM", 6))
742 ret = snprintf(buf, 512, "Power consumption for Memory for this Processor read from APSS");
743 else if (!strncmp(name, "PWRAPSSCH", 9)) {
744 tgt = atoi(name+9);
745 ret = snprintf(buf, 512, "Power Provided by APSS channel %d", tgt);
746 }
747 else
748 ret = snprintf(buf, 512, "[POWER] Unexpected: %s", name);
749 break;
750
751 /* FREQA, FREQACxx */
753 if (!strncmp(name, "FREQACxx", 6)) {
754 tgt = atoi(name+6);
755 ret = snprintf(buf, 512, "Average/actual frequency for this processor, Core %d based on OCA data", tgt);
756 }
757 else if (!strncmp(name, "FREQA", 5))
758 ret = snprintf(buf, 512, "Average of all core frequencies for Processor");
759 else
760 ret = snprintf(buf, 512, "[FREQUENCY] Unexpected: %s", name);
761 break;
762
764 ret = snprintf(buf, 512, "[TIME] Unexpected: %s", name);
765 break;
766
767 /* UTILCxx, UTIL, NUTILCxx, MEMSPSTATMy, MEMSPMy */
769 if (!strncmp(name, "MEMSPSTATM", 10)) {
770 tgt = atoi(name+10);
771 ret = snprintf(buf, 512, "Static Memory throttle level setting for MCA %d when not in a memory throttle condition", tgt);
772 }
773 else if (!strncmp(name, "MEMSPM", 6)) {
774 tgt = atoi(name+6);
775 ret = snprintf(buf, 512, "Current Memory throttle level setting for MCA %d", tgt);
776 }
777 else if (!strncmp(name, "NUTILC", 6)) {
778 tgt = atoi(name+6);
779 ret = snprintf(buf, 512, "Normalized average utilization, rolling average of this Processor's Core %d", tgt);
780 }
781 else if (!strncmp(name, "UTILC", 5)) {
782 tgt = atoi(name+5);
783 ret = snprintf(buf, 512, "Utilization of this Processor's Core %d (where 100%% means fully utilized): NOTE: per thread HW counters are combined as appropriate to give this core level utilization sensor", tgt);
784 }
785 else if (!strncmp(name, "UTIL", 4))
786 ret = snprintf(buf, 512, "Average of all Cores UTILC[yy] sensor");
787 else
788 ret = snprintf(buf, 512, "[UTILIZATION] Unexpected: %s", name);
789 break;
790
791 /* TEMPNEST, TEMPPROCTHRMCxx, TEMPVDD, TEMPDIMMvv, TEMPGPUz, TEMPGPUzMEM*/
793 if (!strncmp(name, "TEMPNEST", 8))
794 ret = snprintf(buf, 512, "Average temperature of nest DTS sensors");
795 else if (!strncmp(name, "TEMPVDD", 7))
796 ret = snprintf(buf, 512, "VRM Vdd temperature");
797 else if (!strncmp(name, "TEMPPROCTHRMCxx", 13)) {
798 tgt = atoi(name+13);
799 ret = snprintf(buf, 512, "The combined weighted core/quad temperature for processor core %d", tgt);
800 }
801 else if (!strncmp(name, "TEMPDIMMvv", 8)) {
802 tgt = atoi(name+8);
803 ret = snprintf(buf, 512, "DIMM temperature for DIMM %d", tgt);
804 }
805 else if (!strncmp(name, "TEMPGPUz", 7)) {
806 char z[] = {name[7], '\0'};
807 tgt = atoi(z);
808 name[7] = 'z';
809 if (!strncmp(name, "TEMPGPUzMEM", 11))
810 ret = snprintf(buf, 512, "GPU %d hottest HBM temperature (individual memory temperatures are not available)", tgt);
811 else if (!strncmp(name, "TEMPGPUz", 8))
812 ret = snprintf(buf, 512, "GPU %d board temperature", tgt);
813 else
814 ret = snprintf(buf, 512, "[TEMPERATURE] Unexpected: GPU-%d %s", tgt, name);
815 }
816 else
817 ret = snprintf(buf, 512, "[TEMPERATURE] Unexpected: %s", name);
818 break;
819
820 /* VOLTVDD, VOLTVDDSENSE, VOLTVDN, VOLTVDNSENSE, VOLTDROOPCNTCx, VOLTDROOPCNTQw */
822 if (!strncmp(name, "VOLTVDDS", 8))
823 ret = snprintf(buf, 512, "Vdn Voltage at the remote sense. (AVS reading adjusted for loadline)");
824 else if (!strncmp(name, "VOLTVDNS", 8))
825 ret = snprintf(buf, 512, "Vdd Voltage at the remote sense. (AVS reading adjusted for loadline)");
826 else if (!strncmp(name, "VOLTVDD", 7))
827 ret = snprintf(buf, 512, "Processor Vdd Voltage (read from AVSBus)");
828 else if (!strncmp(name, "VOLTVDN", 7))
829 ret = snprintf(buf, 512, "Processor Vdn Voltage (read from AVSBus)");
830 else if (!strncmp(name, "VOLTDROOPCNTC", 13)) {
831 tgt = atoi(name+13);
832 ret = snprintf(buf, 512, "Small voltage droop count for core %d", tgt);
833 }
834 else if (!strncmp(name, "VOLTDROOPCNTQ", 13)) {
835 tgt = atoi(name+13);
836 ret = snprintf(buf, 512, "Small voltage droop count for core %d", tgt);
837 }
838 else
839 ret = snprintf(buf, 512, "[VOLTAGE] Unexpected: %s", name);
840 break;
841
842 /* CURVDD, CURVDN */
844 if (!strncmp(name, "CURVDN", 6))
845 ret = snprintf(buf, 512, "Processor Vdn Current (read from AVSBus)");
846 else if (!strncmp(name, "CURVDD", 6))
847 ret = snprintf(buf, 512, "Processor Vdd Current (read from AVSBus)");
848 else
849 ret = snprintf(buf, 512, "[CURRENT] Unexpected: %s", name);
850 break;
851
853 default:
854 ret = snprintf(buf, 512, "[GENERIC] Unexpected: %s", name);
855 break;
856 }
857
858 if (ret <= 0 || 512 <= ret)
859 return PAPI_ENOSUPP;
860 _space_padding(buf, sizeof(buf));
861 ret = snprintf(buf+strlen(buf), 512, "%s", sensors_ppc_fake_qualif_desc[midx]);
862 if (ret <= 0 || 512 <= ret)
863 return PAPI_ENOSUPP;
864 _space_padding(buf, sizeof(buf));
865 ret = snprintf(buf+strlen(buf), 512, "Sampling period: %lfs", 1./freq);
866 if (ret <= 0 || 512 <= ret)
867 return PAPI_ENOSUPP;
868
869 _local_strlcpy( info->long_descr, buf, sizeof(info->long_descr));
871
872 return PAPI_OK;
873}
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_DATATYPE_INT64
Definition: f90papi.h:227
static int _sensors_ppc_is_counter(int index)
static char * _local_strlcpy(char *dst, const char *src, size_t size)
static void _space_padding(char *buf, size_t max)
static const char * sensors_ppc_fake_qualifiers[]
@ OCC_SENSOR_TYPE_GENERIC
@ OCC_SENSOR_TYPE_TIME
@ OCC_SENSOR_TYPE_VOLTAGE
@ OCC_SENSOR_TYPE_FREQUENCY
@ OCC_SENSOR_TYPE_UTILIZATION
@ OCC_SENSOR_TYPE_TEMPERATURE
@ OCC_SENSOR_TYPE_CURRENT
@ OCC_SENSOR_TYPE_POWER
@ OCC_SENSOR_TYPE_PERFORMANCE
@ OCC_SENSORS_ACCUMULATOR_TAG
static const char * sensors_ppc_fake_qualif_desc[]
uint32_t freq
uint16_t type
const char * name
Definition: rocs.c:225
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[MAX_CHARS_SENSOR_UNIT]
Here is the call graph for this function:

◆ _sensors_ppc_ntv_code_to_name()

static int _sensors_ppc_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)
static

Definition at line 602 of file linux-sensors-ppc.c.

603{
604 int index = EventCode & PAPI_NATIVE_AND_MASK;
605
606 if ( index < 0 && index >= occ_num_events[num_occs] )
607 return PAPI_ENOEVNT;
608
609 int s = 0;
610 /* get OCC s from index */
611 for (; index > occ_num_events[s+1] && s < MAX_OCCS; ++s);
612
613 int ridx = index - occ_num_events[s];
614 int gidx = ridx / OCC_SENSORS_MASKS;
615 int midx = ridx % OCC_SENSORS_MASKS;
616
617 /* EventCode maps to a counter */
618 /* Counters only expose their accumulator */
620 return PAPI_ENOEVNT;
621
622 char buf[512];
623 int ret = snprintf(buf, 512, "%s:occ=%d%s", occ_names[s][gidx].name, s, sensors_ppc_fake_qualifiers[midx]);
624 if (ret <= 0 || 512 <= ret)
625 return PAPI_ENOSUPP;
626 _local_strlcpy( name, buf, len);
627
628 return PAPI_OK;
629}
#define PAPI_NATIVE_AND_MASK
Here is the call graph for this function:

◆ _sensors_ppc_ntv_enum_events()

static int _sensors_ppc_ntv_enum_events ( unsigned int EventCode,
int  modifier 
)
static

Definition at line 570 of file linux-sensors-ppc.c.

571{
572 int index;
573 switch (modifier) {
574
575 case PAPI_ENUM_FIRST:
576 *EventCode = 0;
577 return PAPI_OK;
578
579 case PAPI_ENUM_EVENTS:
580 index = *EventCode & PAPI_NATIVE_AND_MASK;
581 if (index < occ_num_events[num_occs] - 1) {
582 if (_sensors_ppc_is_counter(index+1))
583 /* For counters, exposing only the accumulator,
584 * skips ghost events from _sample to _job_sched_max */
585 *EventCode = *EventCode + OCC_SENSORS_MASKS;
586 else
587 *EventCode = *EventCode + 1;
588 return PAPI_OK;
589 } else {
590 return PAPI_ENOEVNT;
591 }
592
593 default:
594 return PAPI_EINVAL;
595 }
596}
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_EINVAL
Definition: f90papi.h:115
Here is the call graph for this function:

◆ _sensors_ppc_read()

static int _sensors_ppc_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
)
static

Definition at line 450 of file linux-sensors-ppc.c.

452{
453 SUBDBG("Enter _sensors_ppc_read\n");
454
455 (void) flags;
458
459 long long start_val = 0;
460 long long curr_val = 0;
461 int c, i;
462
463 /* c is the index in the dense array of selected counters */
464 /* using control->which_counters[c], fetch actual indices in i */
465 /* all subsequent methods use "global" indices i */
466 for ( c = 0; c < num_events; c++ ) {
467 i = control->which_counter[c];
468 start_val = context->start_value[c];
469 curr_val = read_sensors_ppc_value(i);
470
471 if (start_val) {
472 /* Make sure an event is a counter. */
474 /* Wraparound. */
475 if(start_val > curr_val) {
476 curr_val += (0x100000000 - start_val);
477 }
478 /* Normal subtraction. */
479 else if (start_val < curr_val) {
480 curr_val -= start_val;
481 }
482 }
483 }
484 control->count[c]=curr_val;
485 }
486
487 *events = ( ( _sensors_ppc_control_state_t* ) ctl )->count;
488 return PAPI_OK;
489}
int i
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
static long long read_sensors_ppc_value(int index)
long long start_value[SENSORS_PPC_MAX_COUNTERS]
long long count[SENSORS_PPC_MAX_COUNTERS]
long long which_counter[SENSORS_PPC_MAX_COUNTERS]
Here is the call graph for this function:

◆ _sensors_ppc_reset()

static int _sensors_ppc_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 557 of file linux-sensors-ppc.c.

558{
559 (void) ctx;
560 (void) ctl;
561
562 return PAPI_OK;
563}

◆ _sensors_ppc_set_domain()

static int _sensors_ppc_set_domain ( hwd_control_state_t ctl,
int  domain 
)
static

Definition at line 548 of file linux-sensors-ppc.c.

549{
550 (void) ctl;
551 if ( PAPI_DOM_ALL != domain )
552 return PAPI_EINVAL;
553 return PAPI_OK;
554}
#define PAPI_DOM_ALL
Definition: f90papi.h:261

◆ _sensors_ppc_shutdown_component()

static int _sensors_ppc_shutdown_component ( void  )
static

Definition at line 495 of file linux-sensors-ppc.c.

496{
498
499 int s;
501 for (s = 0; s < num_occs; ++s) {
502 free(occ_hdr[s]);
503 if (ping[s] != NULL) free(ping[s]);
504 if (double_ping[s] != NULL) free(double_ping[s]);
505 }
507 return PAPI_OK;
508}
int close(int fd)
Definition: appio.c:179
#define papi_sensors_ppc_lock()
#define papi_sensors_ppc_unlock()
Here is the call graph for this function:

◆ _sensors_ppc_shutdown_thread()

static int _sensors_ppc_shutdown_thread ( hwd_context_t ctx)
static

Definition at line 441 of file linux-sensors-ppc.c.

442{
443 (void) ctx;
444
445 return PAPI_OK;
446}

◆ _sensors_ppc_start()

static int _sensors_ppc_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 409 of file linux-sensors-ppc.c.

410{
411 SUBDBG("Enter _sensors_ppc_start\n");
412
415
416 memset( context->start_value, 0, sizeof(long long) * SENSORS_PPC_MAX_COUNTERS);
417
418 int c, i;
419 for( c = 0; c < num_events; c++ ) {
420 i = control->which_counter[c];
423 }
424
425 /* At the end, ctx->start if full of 0s, except for counter-type sensors */
426 return PAPI_OK;
427}
#define SENSORS_PPC_MAX_COUNTERS
Here is the call graph for this function:

◆ _sensors_ppc_stop()

static int _sensors_ppc_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 430 of file linux-sensors-ppc.c.

431{
432 (void) ctx;
433 (void) ctl;
434
435 /* not sure what the side effect of stop is supposed to be, do a read? */
436 return PAPI_OK;
437}

◆ _sensors_ppc_update_control_state()

static int _sensors_ppc_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)
static

Definition at line 527 of file linux-sensors-ppc.c.

530{
531 (void) ctx;
532 int i, index;
535 if (count == 0) return PAPI_OK;
536
537 /* control contains a dense array of unsorted events */
538 for ( i = 0; i < count; i++ ) {
539 index = native[i].ni_event;
540 control->which_counter[i]=index;
541 native[i].ni_position = i;
542 }
543
544 return PAPI_OK;
545}
static long count
static int native

◆ _space_padding()

static void _space_padding ( char *  buf,
size_t  max 
)
static

Definition at line 49 of file linux-sensors-ppc.c.

50{
51 size_t len = strlen(buf);
52 /* 80 columns - 12 header - 2 footer*/
53 size_t nlines = 1+ len / DESC_LINE_SIZE_ALLOWED, c = len;
54 /* space_padding */
55 for (; c < nlines * DESC_LINE_SIZE_ALLOWED && c < max-1; ++c) buf[c] = ' ';
56 buf[c] = '\0';
57}
#define DESC_LINE_SIZE_ALLOWED
Here is the caller graph for this function:

◆ read_sensors_ppc_counter()

static long long read_sensors_ppc_counter ( int  s,
int  gidx 
)
static

Definition at line 157 of file linux-sensors-ppc.c.

158{
159 uint32_t offset = be32toh(occ_names[s][gidx].reading_offset);
160 uint32_t scale = be32toh(occ_names[s][gidx].scale_factor);
161
162 occ_sensor_counter_t *counter = NULL;
163
164 refresh_data(s, 0);
165
167 occ_sensor_counter_t *sping = (occ_sensor_counter_t *)((uint64_t)ping[s] + offset);
168 occ_sensor_counter_t *spong = (occ_sensor_counter_t *)((uint64_t)pong[s] + offset);
169
170 if (*ping && *pong) {
171 if (be64toh(sping->timestamp) > be64toh(spong->timestamp))
172 counter = sping;
173 else
174 counter = spong;
175 } else if (*ping && !*pong) {
176 counter = sping;
177 } else if (!*ping && *pong) {
178 counter = spong;
179 } else if (!*ping && !*pong) {
180 return 40;
181 }
182
183 uint64_t value = be64toh(counter->accumulator) * TO_FP(scale);
185
186 return value;
187}
#define TO_FP(f)
uint32_t reading_offset
static uint32_t * pong[MAX_OCCS]
uint32_t scale_factor
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_sensors_ppc_record()

static long long read_sensors_ppc_record ( int  s,
int  gidx,
int  midx 
)
static

Definition at line 112 of file linux-sensors-ppc.c.

113{
114 uint64_t value = 41;
115 uint32_t offset = be32toh(occ_names[s][gidx].reading_offset);
116 uint32_t scale = be32toh(occ_names[s][gidx].scale_factor);
117 uint32_t freq = be32toh(occ_names[s][gidx].freq);
118
119 occ_sensor_record_t *record = NULL;
120 /* Let's see if the data segment needs a refresh */
121 refresh_data(s, 0);
122
124 occ_sensor_record_t *sping = (occ_sensor_record_t *)((uint64_t)ping[s] + offset);
125 occ_sensor_record_t *spong = (occ_sensor_record_t *)((uint64_t)pong[s] + offset);
126
127 if (*ping && *pong) {
128 if (be64toh(sping->timestamp) > be64toh(spong->timestamp))
129 record = sping;
130 else
131 record = spong;
132 } else if (*ping && !*pong) {
133 record = sping;
134 } else if (!*ping && *pong) {
135 record = spong;
136 } else if (!*ping && !*pong) {
137 return value;
138 }
139
140 switch (midx) {
142 /* freq, per sensor, contains freq sampling for the last 500us of accumulation */
143 value = (uint64_t)(be64toh(record->accumulator) / TO_FP(freq));
144 break;
145 default:
146 /* That one might upset people
147 * All the entries below sample (including it) are uint16_t packed */
148 value = (uint64_t)(be16toh((&record->sample)[midx]) * TO_FP(scale));
149 break;
150 }
152
153 return value;
154}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_sensors_ppc_value()

static long long read_sensors_ppc_value ( int  index)
static

Definition at line 202 of file linux-sensors-ppc.c.

203{
204 int s = 0;
205 /* get OCC s from index */
206 for (; index > occ_num_events[s+1] && s < MAX_OCCS; ++s);
207
208 int ridx = index - occ_num_events[s];
209 int gidx = ridx / OCC_SENSORS_MASKS;
210 int midx = ridx % OCC_SENSORS_MASKS;
211 uint8_t structure_type = occ_names[s][gidx].structure_type;
212
213 switch (structure_type) {
215 return read_sensors_ppc_record(s, gidx, midx);
217 if (OCC_SENSORS_ACCUMULATOR_TAG == midx)
218 return read_sensors_ppc_counter(s, gidx);
219 /* fall through */
220 /* counters only return the accumulator */
221 default:
222 return 42;
223 }
224}
static long long read_sensors_ppc_record(int s, int gidx, int midx)
static long long read_sensors_ppc_counter(int s, int gidx)
#define OCC_SENSOR_READING_FULL
Here is the call graph for this function:
Here is the caller graph for this function:

◆ refresh_data()

static void refresh_data ( int  occ_id,
int  forced 
)
static

Definition at line 67 of file linux-sensors-ppc.c.

68{
69 long long now = PAPI_get_real_nsec();
70 if (forced || now > last_refresh[occ_id] + OCC_REFRESH_TIME) {
71 void *buf = double_ping[occ_id];
72
73 uint32_t ping_off = be32toh(occ_hdr[occ_id]->reading_ping_offset);
74 uint32_t pong_off = be32toh(occ_hdr[occ_id]->reading_pong_offset);
75
76 lseek (event_fd, occ_id * OCC_SENSOR_DATA_BLOCK_SIZE + ping_off, SEEK_SET);
77
78 /* To limit risks of begin desynchronized, we read one chunk */
79 /* In memory, ping and pong are 40kB, with a 4kB buffer
80 * of nothingness in between */
81 int to_read = pong_off - ping_off + OCC_PING_DATA_BLOCK_SIZE;
82
83 int rc, bytes;
84 /* copy memory iteratively until the full chunk is saved */
85 for (rc = bytes = 0; bytes < to_read; bytes += rc) {
86 rc = read(event_fd, buf + bytes, to_read - bytes);
87 if (!rc || rc < 0) /* done */ break;
88 }
89
91 double_ping[occ_id] = ping[occ_id];
92 ping[occ_id] = buf;
93 pong[occ_id] = ping[occ_id] + (pong_off - ping_off);
94 last_refresh[occ_id] = now;
96 }
97}
Get real time counter value in nanoseconds.
#define OCC_REFRESH_TIME
static long long last_refresh[MAX_OCCS]
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _sensors_ppc_vector

papi_vector_t _sensors_ppc_vector

Definition at line 31 of file linux-sensors-ppc.c.