Skip to content

Commit

Permalink
linux: compute CCD assignment for AMD cpus
Browse files Browse the repository at this point in the history
  • Loading branch information
leahneukirchen authored and BenBE committed Jan 20, 2025
1 parent 8266759 commit c079bcc
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
32 changes: 32 additions & 0 deletions linux/LibSensors.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,38 @@ static int tempDriverPriority(const sensors_chip_name* chip) {
return -1;
}

int LibSensors_countCCDs(void) {

#ifndef BUILD_STATIC
if (!dlopenHandle)
return 0;
#endif /* !BUILD_STATIC */

int ccds = 0;

int n = 0;
for (const sensors_chip_name* chip = sym_sensors_get_detected_chips(NULL, &n); chip; chip = sym_sensors_get_detected_chips(NULL, &n)) {
int m = 0;
for (const sensors_feature* feature = sym_sensors_get_features(chip, &m); feature; feature = sym_sensors_get_features(chip, &m)) {
if (feature->type != SENSORS_FEATURE_TEMP)
continue;

if (!feature->name || !String_startsWith(feature->name, "temp"))
continue;

char *label = sym_sensors_get_label(chip, feature);
if (label) {
if (String_startsWith(label, "Tccd")) {
ccds++;
}
free(label);
}
}
}

return ccds;
}

void LibSensors_getCPUTemperatures(CPUData* cpus, unsigned int existingCPUs, unsigned int activeCPUs) {
assert(existingCPUs > 0 && existingCPUs < 16384);

Expand Down
1 change: 1 addition & 0 deletions linux/LibSensors.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ int LibSensors_init(void);
void LibSensors_cleanup(void);
int LibSensors_reload(void);

int LibSensors_countCCDs(void);
void LibSensors_getCPUTemperatures(CPUData* cpus, unsigned int existingCPUs, unsigned int activeCPUs);

#endif /* HEADER_LibSensors */
43 changes: 43 additions & 0 deletions linux/LinuxMachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,47 @@ static void LinuxMachine_fetchCPUTopologyFromCPUinfo(LinuxMachine* this) {

fclose(file);
}

static void LinuxMachine_assignCCDs(LinuxMachine* this, int ccds) {
/* For AMD k10temp/zenpower, temperatures are provided for CCDs only,
which is an aggregate of multiple cores.
There's no obvious mapping between hwmon sensors and sockets and CCDs.
Assume both are iterated in order.
Hypothesis: Each CCD has same size N = #Cores/#CCD
and is assigned N coreID in sequence.
Also assume all CPUs have same number of CCDs. */

const Machine* super = &this->super;
CPUData *cpus = this->cpuData;

if (ccds == 0) {
for (size_t i = 0; i < super->existingCPUs + 1; i++) {
cpus[i].ccdID = -1;
}
return;
}

int coresPerCCD = super->existingCPUs / ccds;

int ccd = 0;
int nc = coresPerCCD;
for (int p = 0; p <= (int)this->maxPhysicalID; p++) {
for (int c = 0; c <= (int)this->maxCoreID; c++) {
for (size_t i = 1; i <= super->existingCPUs; i++) {
if (cpus[i].physicalID != p || cpus[i].coreID != c)
continue;

cpus[i].ccdID = ccd;

if (--nc <= 0) {
nc = coresPerCCD;
ccd++;
}
}
}
}
}

#endif

static void LinuxMachine_scanCPUFrequency(LinuxMachine* this) {
Expand Down Expand Up @@ -749,6 +790,8 @@ Machine* Machine_new(UsersTable* usersTable, uid_t userId) {
#ifdef HAVE_SENSORS_SENSORS_H
// Fetch CPU topology
LinuxMachine_fetchCPUTopologyFromCPUinfo(this);
int ccds = LibSensors_countCCDs();
LinuxMachine_assignCCDs(this, ccds);
#endif

return super;
Expand Down
1 change: 1 addition & 0 deletions linux/LinuxMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typedef struct CPUData_ {

int physicalID; /* different for each CPU socket */
int coreID; /* same for hyperthreading */
int ccdID; /* same for each AMD chiplet */
#endif

bool online;
Expand Down

0 comments on commit c079bcc

Please sign in to comment.