[v0.11] Fetch and print max Intel iGPU frequency using sysfs

This commit is contained in:
Dr-Noob
2021-12-09 20:18:39 +01:00
parent 844377f17a
commit 1663a36135
7 changed files with 123 additions and 1 deletions

View File

@@ -54,7 +54,7 @@ set(CMAKE_CXX_FLAGS "${SANITY_FLAGS} -Wall -Wextra -pedantic -fstack-protector-a
if(ENABLE_INTEL_BACKEND) if(ENABLE_INTEL_BACKEND)
target_compile_definitions(gpufetch PUBLIC BACKEND_INTEL) target_compile_definitions(gpufetch PUBLIC BACKEND_INTEL)
add_library(intel_backend STATIC ${INTEL_DIR}/intel.cpp ${INTEL_DIR}/pci.cpp ${INTEL_DIR}/uarch.cpp) add_library(intel_backend STATIC ${INTEL_DIR}/intel.cpp ${INTEL_DIR}/pci.cpp ${INTEL_DIR}/uarch.cpp ${INTEL_DIR}/udev.cpp)
if(NOT ${PCIUTILS_FOUND}) if(NOT ${PCIUTILS_FOUND})
add_dependencies(intel_backend pciutils) add_dependencies(intel_backend pciutils)

View File

@@ -26,11 +26,29 @@ uint16_t pciutils_get_pci_device_id(struct pci_dev *devices, int id) {
return 0; return 0;
} }
void pciutils_set_pci_bus(struct pci* pci, struct pci_dev *devices, int id) {
bool found = false;
for(struct pci_dev *dev=devices; dev != NULL; dev=dev->next) {
if(dev->vendor_id == id && dev->device_class == CLASS_VGA_CONTROLLER) {
pci->domain = dev->domain;
pci->bus = dev->bus;
pci->dev = dev->dev;
pci->func = dev->func;
found = true;
}
}
if(!found) printErr("Unable to find a valid device for id %d using pciutils", id);
}
struct pci* get_pci_from_pciutils(struct pci_dev *devices, int id) { struct pci* get_pci_from_pciutils(struct pci_dev *devices, int id) {
struct pci* pci = (struct pci*) emalloc(sizeof(struct pci)); struct pci* pci = (struct pci*) emalloc(sizeof(struct pci));
// TODO: Refactor this; instead of 2xGet + 1xSet, do it better
pci->vendor_id = pciutils_get_pci_vendor_id(devices, id); pci->vendor_id = pciutils_get_pci_vendor_id(devices, id);
pci->device_id = pciutils_get_pci_device_id(devices, id); pci->device_id = pciutils_get_pci_device_id(devices, id);
pciutils_set_pci_bus(pci, devices, id);
return pci; return pci;
} }

View File

@@ -9,6 +9,10 @@ extern "C" {
struct pci { struct pci {
uint16_t vendor_id; uint16_t vendor_id;
uint16_t device_id; uint16_t device_id;
uint16_t domain;
uint16_t bus;
uint16_t dev;
uint16_t func;
}; };
struct pci* get_pci_from_pciutils(struct pci_dev *devices, int id); struct pci* get_pci_from_pciutils(struct pci_dev *devices, int id);

View File

@@ -371,10 +371,12 @@ bool print_gpufetch_intel(struct gpu_info* gpu, STYLE s, struct color** cs, stru
char* gt = get_str_gt(gpu->arch); char* gt = get_str_gt(gpu->arch);
char* manufacturing_process = get_str_process(gpu->arch); char* manufacturing_process = get_str_process(gpu->arch);
char* eus = get_str_eu(gpu); char* eus = get_str_eu(gpu);
char* max_frequency = get_str_freq(gpu);
setAttribute(art, ATTRIBUTE_NAME, gpu_name); setAttribute(art, ATTRIBUTE_NAME, gpu_name);
setAttribute(art, ATTRIBUTE_UARCH, uarch); setAttribute(art, ATTRIBUTE_UARCH, uarch);
setAttribute(art, ATTRIBUTE_TECHNOLOGY, manufacturing_process); setAttribute(art, ATTRIBUTE_TECHNOLOGY, manufacturing_process);
setAttribute(art, ATTRIBUTE_FREQUENCY, max_frequency);
setAttribute(art, ATTRIBUTE_GT, gt); setAttribute(art, ATTRIBUTE_GT, gt);
setAttribute(art, ATTRIBUTE_EUS, eus); setAttribute(art, ATTRIBUTE_EUS, eus);

View File

@@ -4,6 +4,7 @@
#include "intel.hpp" #include "intel.hpp"
#include "uarch.hpp" #include "uarch.hpp"
#include "chips.hpp" #include "chips.hpp"
#include "udev.hpp"
#include "../common/pci.hpp" #include "../common/pci.hpp"
#include "../common/global.hpp" #include "../common/global.hpp"
@@ -16,6 +17,7 @@ struct gpu_info* get_gpu_info_intel() {
gpu->arch = get_uarch_from_pci(gpu->pci); gpu->arch = get_uarch_from_pci(gpu->pci);
gpu->name = get_name_from_uarch(gpu->arch); gpu->name = get_name_from_uarch(gpu->arch);
gpu->topo_i = get_topology_info(gpu->arch); gpu->topo_i = get_topology_info(gpu->arch);
gpu->freq = get_max_freq_from_file(gpu->pci);
return gpu; return gpu;
} }

89
src/intel/udev.cpp Normal file
View File

@@ -0,0 +1,89 @@
#include <cstddef>
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <cerrno>
#include <cstdio>
#include <fcntl.h>
#include <unistd.h>
#include "../common/global.hpp"
#include "../common/pci.hpp"
#define _PATH_SYS_SYSTEM "/sys/devices/pci0000:00"
#define _PATH_SYS_DRM "/drm"
#define _PATH_CARD "/card0"
#define _PATH_FREQUENCY_MAX "/gt_max_freq_mhz"
#define _PATH_FREQUENCY_MIN "/gt_min_freq_mhz"
#define _PATH_FREQUENCY_MAX_LEN 100
#define DEFAULT_FILE_SIZE 4096
#define UNKNOWN_DATA -1
char* read_file(char* path, int* len) {
int fd = open(path, O_RDONLY);
if(fd == -1) {
return NULL;
}
//File exists, read it
int bytes_read = 0;
int offset = 0;
int block = 128;
char* buf = (char *) emalloc(sizeof(char)*DEFAULT_FILE_SIZE);
memset(buf, 0, sizeof(char)*DEFAULT_FILE_SIZE);
while ( (bytes_read = read(fd, buf+offset, block)) > 0 ) {
offset += bytes_read;
}
if (close(fd) == -1) {
return NULL;
}
*len = offset;
return buf;
}
long get_freq_from_file(char* path) {
int filelen;
char* buf;
if((buf = read_file(path, &filelen)) == NULL) {
printWarn("Could not open '%s'", path);
return UNKNOWN_DATA;
}
char* end;
errno = 0;
long ret = strtol(buf, &end, 10);
if(errno != 0) {
printBug("strtol: %s", strerror(errno));
free(buf);
return UNKNOWN_DATA;
}
// We will be getting the frequency in MHz
// We consider it is an error if frequency is
// greater than 10 GHz or less than 100 MHz
if(ret > 10000 || ret < 100) {
printBug("Invalid data was read from file '%s': %ld\n", path, ret);
return UNKNOWN_DATA;
}
free(buf);
return ret;
}
long get_max_freq_from_file(struct pci* pci) {
char path[_PATH_FREQUENCY_MAX_LEN];
sprintf(path, "%s/%04x:%02x:%02x.%d%s%s%s", _PATH_SYS_SYSTEM, pci->domain, pci->bus, pci->dev, pci->func, _PATH_SYS_DRM, _PATH_CARD, _PATH_FREQUENCY_MAX);
return get_freq_from_file(path);
}
long get_min_freq_from_file(struct pci* pci) {
char path[_PATH_FREQUENCY_MAX_LEN];
sprintf(path, "%s/%04x:%02x:%02x.%d%s%s%s", _PATH_SYS_SYSTEM, pci->domain, pci->bus, pci->dev, pci->func, _PATH_SYS_DRM, _PATH_CARD, _PATH_FREQUENCY_MIN);
return get_freq_from_file(path);
}

7
src/intel/udev.hpp Normal file
View File

@@ -0,0 +1,7 @@
#ifndef __UDEV__
#define __UDEV__
long get_max_freq_from_file(struct pci* pci);
long get_min_freq_from_file(struct pci* pci);
#endif