Skip to content

Commit

Permalink
Linux: scan GPU based on previous activity
Browse files Browse the repository at this point in the history
Instead of ignoring the standard file descriptors 0, 1 and 2 scan for
GPU usage of a process only if that process had activity last cycle or
its last scan was more than five seconds ago.
  • Loading branch information
cgzones committed Jan 7, 2024
1 parent b1ac415 commit ce362dc
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
17 changes: 11 additions & 6 deletions linux/GPU.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,19 @@ static void update_machine_gpu(LinuxProcessTable* lpt, unsigned long long int ti
* https://www.kernel.org/doc/html/latest/gpu/drm-usage-stats.html
*/
void GPU_readProcessData(LinuxProcessTable* lpt, LinuxProcess* lp, openat_arg_t procFd) {
const Machine* host = lp->super.super.host;
int fdinfoFd = -1;
DIR* fdinfoDir = NULL;
struct client_id* parsed_ids = NULL;
unsigned long long int new_gpu_time = 0;

/* check only if active in last check or last scan was more than 5s ago */
if (lp->gpu_activityMs != 0 && host->monotonicMs - lp->gpu_activityMs < 5000) {
lp->gpu_percent = 0.0f;
return;
}
lp->gpu_activityMs = host->monotonicMs;

fdinfoFd = Compat_openat(procFd, "fdinfo", O_RDONLY | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
if (fdinfoFd == -1)
goto out;
Expand All @@ -110,11 +118,7 @@ void GPU_readProcessData(LinuxProcessTable* lpt, LinuxProcess* lp, openat_arg_t
break;
const char* ename = entry->d_name;

if (String_eq(ename, ".") ||
String_eq(ename, "..") ||
String_eq(ename, "0") ||
String_eq(ename, "1") ||
String_eq(ename, "2"))
if (ename[0] == '.' && (ename[1] == '\0' || (ename[1] == '.' && ename[2] == '\0')))
continue;

char buffer[4096];
Expand Down Expand Up @@ -217,7 +221,6 @@ void GPU_readProcessData(LinuxProcessTable* lpt, LinuxProcess* lp, openat_arg_t
} /* finished parsing fdinfo entries */

if (new_gpu_time > 0) {
const Machine* host = lp->super.super.host;
unsigned long long int gputimeDelta;
uint64_t monotonicTimeDelta;

Expand All @@ -226,6 +229,8 @@ void GPU_readProcessData(LinuxProcessTable* lpt, LinuxProcess* lp, openat_arg_t
gputimeDelta = saturatingSub(new_gpu_time, lp->gpu_time);
monotonicTimeDelta = host->monotonicMs - host->prevMonotonicMs;
lp->gpu_percent = 100.0f * gputimeDelta / (1000 * 1000) / monotonicTimeDelta;

lp->gpu_activityMs = 0;
} else
lp->gpu_percent = 0.0f;

Expand Down
2 changes: 2 additions & 0 deletions linux/LinuxProcess.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ typedef struct LinuxProcess_ {
unsigned long long int gpu_time;
/* GPU utilization in percent */
float gpu_percent;
/* Activity of GPU: 0 if active, otherwise time of last scan in milliseconds */
uint64_t gpu_activityMs;

/* Autogroup scheduling (CFS) information */
long int autogroup_id;
Expand Down

0 comments on commit ce362dc

Please sign in to comment.