From 0318589c8bc3de6132af7f7d197295f58d89424b 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: 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 7b6ef886..37d5d7c4 100644 --- a/linux/GPU.c +++ b/linux/GPU.c @@ -79,11 +79,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; ClientInfo* 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; @@ -108,11 +116,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]; @@ -211,7 +215,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; @@ -220,6 +223,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 cc515f5f..5a1e6272 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; -- cgit v1.2.3