From 4f7213e6e742b993feeaf300181a67923e60c0f4 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Wed, 10 May 2023 02:26:29 +0000 Subject: [PATCH] gpu/nvidia: Discover data fields based on headers This guards us against the appearance of new fields or if they ever appear in a different order. BUG:470474 FIXED-IN:5.27.7 (cherry picked from commit 7f9ead6bddfdf6f13a1ea48791f8f5d5c80c6980) Because in Qt5 QVector::indexOf only takes T's we have to provide our own indexOf here. --- plugins/gpu/NvidiaSmiProcess.cpp | 56 ++++++++++++++++++++++---------- plugins/gpu/NvidiaSmiProcess.h | 14 ++++++++ 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/plugins/gpu/NvidiaSmiProcess.cpp b/plugins/gpu/NvidiaSmiProcess.cpp index 7f8dd62..d92b396 100644 --- a/plugins/gpu/NvidiaSmiProcess.cpp +++ b/plugins/gpu/NvidiaSmiProcess.cpp @@ -155,19 +155,37 @@ void NvidiaSmiProcess::unref() void NvidiaSmiProcess::readStatisticsData() { while (m_process->canReadLine()) { - const QString line = m_process->readLine(); - if (line.startsWith(QLatin1Char('#'))) { - continue; - } + QString line = m_process->readLine(); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - const QVector parts = QStringRef(&line).trimmed().split(QLatin1Char(' '), Qt::SkipEmptyParts); + QVector parts = QStringRef(&line).trimmed().split(QLatin1Char(' '), Qt::SkipEmptyParts); #else - const QVector parts = QStringView(line).trimmed().split(QLatin1Char(' '), Qt::SkipEmptyParts); + QVector parts = QStringView(line).trimmed().split(QLatin1Char(' '), Qt::SkipEmptyParts); #endif - - // format at time of writing is - // # gpu pwr gtemp mtemp sm mem enc dec mclk pclk fb bar1 - if (parts.count() != 12) { + // Because in Qt5 indexOf of QVector only takes T's, write our own indexOf taking arbitrary types + auto indexOf = [](const auto &stack, const auto& needle) { + auto it = std::find(stack.cbegin(), stack.cend(), needle); + return it != stack.cend() ? std::distance(stack.cbegin(), it) : -1; + }; + + // discover index of fields in the header format is something like + //# gpu pwr gtemp mtemp sm mem enc dec mclk pclk fb bar1 + // # Idx W C C % % % % MHz MHz MB MB + // 0 25 29 - 1 1 0 0 4006 1506 891 22 + if (line.startsWith(QLatin1Char('#'))) { + if (m_dmonIndices.gpu == -1) { + // Remove First part because of leading '# '; + parts.removeFirst(); + m_dmonIndices.gpu = indexOf(parts, QLatin1String("gpu")); + m_dmonIndices.power = indexOf(parts, QLatin1String("pwr")); + m_dmonIndices.gtemp = indexOf(parts, QLatin1String("gtemp")); + m_dmonIndices.sm = indexOf(parts, QLatin1String("sm")); + m_dmonIndices.enc = indexOf(parts, QLatin1String("enc")); + m_dmonIndices.dec = indexOf(parts, QLatin1String("dec")); + m_dmonIndices.fb = indexOf(parts, QLatin1String("fb")); + m_dmonIndices.bar1 = indexOf(parts, QLatin1String("bar1")); + m_dmonIndices.mclk = indexOf(parts, QLatin1String("mclk")); + m_dmonIndices.pclk = indexOf(parts, QLatin1String("pclk")); + } continue; } @@ -177,19 +195,23 @@ void NvidiaSmiProcess::readStatisticsData() continue; } + auto readDataIfFound = [&parts, this] (int index) { + return index > 0 ? parts[index].toUInt() : 0; + }; + GpuData data; - data.index = index; - data.power = parts[1].toUInt(); - data.temperature = parts[2].toUInt(); + data.index = readDataIfFound(m_dmonIndices.gpu); + data.power = readDataIfFound(m_dmonIndices.power); + data.temperature = readDataIfFound(m_dmonIndices.gtemp); // GPU usage equals "SM" usage + "ENC" usage + "DEC" usage - data.usage = parts[4].toUInt() + parts[6].toUInt() + parts[7].toUInt(); + data.usage = readDataIfFound(m_dmonIndices.sm) + readDataIfFound(m_dmonIndices.enc) + readDataIfFound(m_dmonIndices.dec); // Total memory used equals "FB" usage + "BAR1" usage - data.memoryUsed = parts[10].toUInt() + parts[11].toUInt(); + data.memoryUsed = readDataIfFound(m_dmonIndices.fb) + readDataIfFound(m_dmonIndices.bar1); - data.memoryFrequency = parts[8].toUInt(); - data.coreFrequency = parts[9].toUInt(); + data.memoryFrequency = readDataIfFound(m_dmonIndices.mclk); + data.coreFrequency = readDataIfFound(m_dmonIndices.pclk); Q_EMIT dataReceived(data); } diff --git a/plugins/gpu/NvidiaSmiProcess.h b/plugins/gpu/NvidiaSmiProcess.h index f39cc9d..2cd8504 100644 --- a/plugins/gpu/NvidiaSmiProcess.h +++ b/plugins/gpu/NvidiaSmiProcess.h @@ -49,8 +49,22 @@ public: private: void readStatisticsData(); + struct dmonIndices { + int gpu = -1; + int gtemp = -1; + int power = -1; + int sm = -1; + int enc = -1; + int dec = -1; + int fb = -1; + int bar1 = -1; + int mclk = -1; + int pclk = -1; + }; + QString m_smiPath; std::vector m_queryResult; std::unique_ptr m_process = nullptr; int m_references = 0; + dmonIndices m_dmonIndices; }; -- GitLab