From ce362dc68d6b22f272677ddc767d040771dc072e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Sun, 5 Nov 2023 17:31:16 +0100 Subject: [PATCH] Linux: scan GPU based on previous activity 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. --- linux/GPU.c | 17 +++++++++++------ linux/LinuxProcess.h | 2 ++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/linux/GPU.c b/linux/GPU.c index 5bb0d974c..0d3f53701 100644 --- a/linux/GPU.c +++ b/linux/GPU.c @@ -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; @@ -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]; @@ -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; @@ -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; diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h index cc515f5f0..5a1e62725 100644 --- a/linux/LinuxProcess.h +++ b/linux/LinuxProcess.h @@ -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;