int access_x86_pci_init(const int socket) { int ret = 0; if (access_x86_initialized == 0) { uint16_t testDevice; ownaccess = &access; ownopen = &open; /* PCI is only provided by Intel systems */ if (!cpuid_info.isIntel) { DEBUG_PLAIN_PRINT(DEBUGLEV_DETAIL, PCI based Uncore performance monitoring only supported on Intel systems); return -ENODEV; } switch (cpuid_info.model) { case SANDYBRIDGE_EP: testDevice = 0x3c44; break; case IVYBRIDGE_EP: testDevice = 0x0e36; break; case HASWELL_EP: testDevice = 0x2f30; break; case BROADWELL_D: testDevice = 0x6f30; break; default: DEBUG_PRINT(DEBUGLEV_INFO,CPU model %s does not support PCI based Uncore performance monitoring, cpuid_info.name); return -ENODEV; break; } if(geteuid() != 0) { fprintf(stderr, "WARNING\n"); fprintf(stderr, "Direct access to the PCI Cfg Adressspace is only allowed for uid root!\n"); fprintf(stderr, "This means you can use performance groups as MEM only as root in direct mode.\n"); fprintf(stderr, "Alternatively you might want to look into (sys)daemonmode.\n\n"); return -EPERM; } for(int i=0; i<MAX_NUM_NODES; i++) { for(int j=1;j<MAX_NUM_PCI_DEVICES;j++) { FD[i][j] = -2; } } #ifdef LIKWID_USE_HWLOC DEBUG_PLAIN_PRINT(DEBUGLEV_DETAIL, Using hwloc to find pci devices); ret = hwloc_pci_init(testDevice, socket_bus, &nr_sockets); if (ret) { ERROR_PLAIN_PRINT(Using hwloc to find pci devices failed); return -ENODEV; } #else DEBUG_PLAIN_PRINT(DEBUGLEV_DETAIL, Using procfs to find pci devices); ret = proc_pci_init(testDevice, socket_bus, &nr_sockets); if (ret) { ERROR_PLAIN_PRINT(Using procfs to find pci devices failed); return -ENODEV; } #endif } for(int j=1;j<MAX_NUM_PCI_DEVICES;j++) { if ((pci_devices[j].path != NULL) && (FD[socket][j] == -2)) { bstring filepath = bformat("%s%s%s",PCI_ROOT_PATH, socket_bus[socket], pci_devices[j].path); if (!ownaccess(bdata(filepath),X_OK)) { FD[socket][j] = 0; pci_devices[j].online = 1; if (access_x86_initialized == 0) { DEBUG_PRINT(DEBUGLEV_DETAIL, PCI device %s (%d) online for socket %d at path %s, pci_devices[j].name,j, socket,bdata(filepath)); if (!ownaccess(bdata(filepath),R_OK|W_OK)) { ERROR_PRINT(PCI device %s (%d) online for socket %d at path %s but not accessible, pci_devices[j].name,j, socket,bdata(filepath)); } }
int pci_init(int initSocket_fd) { uint16_t testDevice; int nr_sockets = 0; int i=0; int j=0; int ret = 0; int access_flags = 0; ownaccess = &access; ownopen = &open; for (i=0; i<MAX_NUM_NODES; i++ ) { socket_bus[i] = "N-A"; for(j=1;j<MAX_NUM_PCI_DEVICES;j++) { FD[i][j] = -2; } } /* PCI is only provided by Intel systems */ if (!cpuid_info.isIntel) { DEBUG_PLAIN_PRINT(DEBUGLEV_DETAIL, PCI based Uncore performance monitoring only supported on Intel systems); return -ENODEV; } switch (cpuid_info.model) { case SANDYBRIDGE_EP: testDevice = 0x3c44; break; case IVYBRIDGE_EP: testDevice = 0x0e36; break; case HASWELL_EP: testDevice = 0x2f30; break; default: DEBUG_PRINT(DEBUGLEV_INFO,CPU model %s does not support PCI based Uncore performance monitoring, cpuid_info.name); return -ENODEV; break; } #ifdef LIKWID_USE_HWLOC DEBUG_PLAIN_PRINT(DEBUGLEV_DETAIL, Using hwloc to find pci devices); ret = hwloc_pci_init(testDevice, socket_bus, &nr_sockets); if (ret) { ERROR_PLAIN_PRINT(Using hwloc to find pci devices failed); return -ENODEV; } #else DEBUG_PLAIN_PRINT(DEBUGLEV_DETAIL, Using procfs to find pci devices); ret = proc_pci_init(testDevice, socket_bus, &nr_sockets); if (ret) { ERROR_PLAIN_PRINT(Using procfs to find pci devices failed); return -ENODEV; } #endif if (accessClient_mode == ACCESSMODE_DIRECT) { access_flags = R_OK|W_OK; } else { access_flags = F_OK; } for(i=0;i<nr_sockets;i++) { for(j=1;j<MAX_NUM_PCI_DEVICES;j++) { if (pci_devices[j].path != NULL) { bstring filepath = bformat("%s%s%s",PCI_ROOT_PATH, socket_bus[i], pci_devices[j].path); if (!ownaccess(bdata(filepath),access_flags)) { FD[i][j] = 0; pci_devices[j].online = 1; if (i==0) { DEBUG_PRINT(DEBUGLEV_DETAIL, PCI device %s (%d) online for socket %d at path %s, pci_devices[j].name,j, i,bdata(filepath)); } } else {
int power_init(int cpuId) { uint64_t flags; int i; int err; /* determine Turbo Mode features */ double busSpeed; power_info.baseFrequency = 0; power_info.minFrequency = 0; power_info.turbo.numSteps = 0; power_info.powerUnit = 0; power_info.timeUnit = 0; power_info.hasRAPL = 0; switch (cpuid_info.model) { case SANDYBRIDGE: case IVYBRIDGE: case HASWELL: case SANDYBRIDGE_EP: case IVYBRIDGE_EP: case HASWELL_EP: case ATOM_SILVERMONT_E: case ATOM_SILVERMONT_Z1: case ATOM_SILVERMONT_Z2: case ATOM_SILVERMONT_F: case BROADWELL: case BROADWELL_E: case BROADWELL_D: power_info.hasRAPL = 1; break; case ATOM_SILVERMONT_C: power_info.hasRAPL = 1; /* The info_regs list needs an update for Silvermont Type C because it uses another info register */ info_regs[PKG] = MSR_PKG_POWER_INFO_SILVERMONT; break; default: DEBUG_PLAIN_PRINT(DEBUGLEV_INFO, NO RAPL SUPPORT); return 0; break; } perfmon_init_maps(); if (!HPMinitialized()) { HPMaddThread(cpuId); } if (power_initialized) { return 0; } if ( power_info.hasRAPL ) { busSpeed = 100.0; } else { busSpeed = 133.33; } if (cpuid_info.turbo) { err = HPMread(cpuId, MSR_DEV, MSR_PLATFORM_INFO, &flags); if (err == 0) { power_info.baseFrequency = busSpeed * (double) extractBitField(flags,8,8); power_info.minFrequency = busSpeed * (double) extractBitField((flags>>(32)),8,8); power_info.turbo.numSteps = cpuid_topology.numCoresPerSocket; if (cpuid_info.model == WESTMERE_EX) { power_info.turbo.numSteps = 4; } power_info.turbo.steps = (double*) malloc(power_info.turbo.numSteps * sizeof(double)); if (!power_info.turbo.steps) { return -ENOMEM; } err = HPMread(cpuId, MSR_DEV, MSR_TURBO_RATIO_LIMIT, &flags); if (err) { fprintf(stderr,"Cannot gather values from MSR_TURBO_RATIO_LIMIT,\n"); } else { for (int i=0; i < power_info.turbo.numSteps; i++) { if (i < 8) { power_info.turbo.steps[i] = busSpeed * (double) field64(flags,i*8, 8); } else { power_info.turbo.steps[i] = power_info.turbo.steps[7]; } } } //TODO: Haswell EP and possibly Broadwell EP support multiple turbo // registers besides MSR_TURBO_RATIO_LIMIT: // MSR_TURBO_RATIO_LIMIT1 and MSR_TURBO_RATIO_LIMIT2 }