Fix: [gpu-info] The gpu mem not show.#543
Fix: [gpu-info] The gpu mem not show.#543deepin-bot[bot] merged 1 commit intolinuxdeepin:develop/eaglefrom
Conversation
-- Adjust code logic to show gpu mem. Log: fix issue Bug: https://pms.uniontech.com/bug-view-336355.html
Reviewer's GuideThis PR replaces the legacy external GPU info commands with a direct sysfs reader for GPU memory, exposes it via a new D-Bus method, and integrates it into the existing GPU info flow while removing obsolete code. Sequence diagram for GPU memory info retrieval via D-BussequenceDiagram
participant App
participant CommonTools
participant QDBusInterface
participant DeviceInfoServer
participant DeviceInterface
App->>CommonTools: preGenerateGpuInfo()
CommonTools->>QDBusInterface: call("getGpuInfoForFTDTM")
QDBusInterface->>DeviceInfoServer: D-Bus call getGpuInfoForFTDTM
DeviceInfoServer->>DeviceInterface: getGpuMemInfoForFTDTM(mapInfo)
DeviceInterface->>DeviceInterface: Read /sys/kernel/debug/gc/total_mem
DeviceInterface->>DeviceInterface: Parse and format memory info
DeviceInterface-->>DeviceInfoServer: Return GPU memory info
DeviceInfoServer-->>QDBusInterface: Return GPU memory info
QDBusInterface-->>CommonTools: Return GPU memory info
CommonTools-->>App: Return combined GPU info
Class diagram for updated DeviceInterface and related GPU info retrievalclassDiagram
class DeviceInterface {
+setMonitorDeviceFlag(bool flag)
+getGpuInfoForFTDTM()
-getUserAuthorPasswd()
-getGpuMemInfoForFTDTM(QMap<QString, QString> &mapInfo)
}
class CommonTools {
+preGenerateGpuInfo()
-getGpuBaseInfo(QMap<QString, QString> &mapInfo)
}
class QDBusInterface {
+call(method)
}
DeviceInterface <|-- DeviceInfoServer
CommonTools --> QDBusInterface : uses
QDBusInterface --> DeviceInfoServer : D-Bus call
DeviceInfoServer --> DeviceInterface : calls
CommonTools --> DeviceInterface : via D-Bus
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
deepin pr auto review根据提供的代码差异,我来对代码进行审查,并提出改进意见:
具体改进建议:
bool DeviceInterface::getGpuMemInfoForFTDTM(QMap<QString, QString> &mapInfo)
{
const QString filePath = "/sys/kernel/debug/gc/total_mem";
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCritical() << "Error opening file:" << file.errorString();
return false;
}
QTextStream in(&file);
QString content = in.readAll();
file.close();
if (content.isEmpty()) {
qCritical() << "Error: File is empty!";
return false;
}
// 其余代码...
}
static const QRegularExpression kMemInfoRegex(R"((\d+(?:\.\d+)?)\s*\(?(MB|GB|KB|B)\)?)",
QRegularExpression::CaseInsensitiveOption);
bool DeviceInterface::getGpuMemInfoForFTDTM(QMap<QString, QString> &mapInfo)
{
// ... 前面的文件操作代码 ...
QRegularExpressionMatch match = kMemInfoRegex.match(content.trimmed());
if (!match.hasMatch()) {
qCritical() << "Error: Failed to parse memory info";
return false;
}
// ... 其余代码 ...
}
QString DeviceInterface::convertToGB(double value, const QString &unit)
{
static const QMap<QString, double> unitFactors = {
{"B", 1.0 / (1024.0 * 1024.0 * 1024.0)},
{"KB", 1.0 / (1024.0 * 1024.0)},
{"MB", 1.0 / 1024.0},
{"GB", 1.0}
};
auto it = unitFactors.find(unit.toUpper());
if (it == unitFactors.end()) {
qCritical() << "Error: Unsupported unit:" << unit;
return QString();
}
return QString("%1GB").arg(value * it.value(), 0, 'f', 2);
}
这些改进将提高代码的健壮性、可维护性和性能。同时,良好的错误处理和日志记录将有助于问题的快速定位和解决。 |
There was a problem hiding this comment.
Hey there - I've reviewed your changes - here's some feedback:
- Add an explicit fallback or error branch in getGpuMemInfoForFTDTM for unrecognized units so totalValue doesn’t remain empty if the regex captures an unexpected unit.
- Static caching of GPU info means it will never refresh at runtime; consider adding a cache invalidation or refresh trigger to pick up memory updates after the first call.
- Both DeviceInterface and CommonTools contain similar loops to build the key:value strings from a QMap—extract that into a shared helper function to reduce code duplication.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Add an explicit fallback or error branch in getGpuMemInfoForFTDTM for unrecognized units so totalValue doesn’t remain empty if the regex captures an unexpected unit.
- Static caching of GPU info means it will never refresh at runtime; consider adding a cache invalidation or refresh trigger to pick up memory updates after the first call.
- Both DeviceInterface and CommonTools contain similar loops to build the key:value strings from a QMap—extract that into a shared helper function to reduce code duplication.
## Individual Comments
### Comment 1
<location> `deepin-devicemanager-server/deepin-deviceinfo/src/loadinfo/deviceinterface.cpp:32` </location>
<code_context>
return result == Authority::Yes;
}
+bool DeviceInterface::getGpuMemInfoForFTDTM(QMap<QString, QString> &mapInfo)
+{
+ const QString filePath = "/sys/kernel/debug/gc/total_mem";
</code_context>
<issue_to_address>
**issue (complexity):** Consider refactoring the method by extracting helpers, using a unit conversion map, and simplifying formatting with join().
Here are a few low-risk refactorings you can apply to keep the exact same behaviour but break that monster method into bite-sized helpers, remove the deep if/else, and collapse your formatting loop into a single `join()`.
1) pull the file-read and empty-check out into its own helper:
```cpp
static QString readFileContent(const QString& path) {
QFile f(path);
if (!f.open(QIODevice::ReadOnly|QIODevice::Text)) {
qCritical() << "Error opening" << path << ":" << f.errorString();
return {};
}
return QString::fromUtf8(f.readAll()).trimmed();
}
```
2) pull the regex match into a helper + make the regex `static const` so it isn’t reallocated every call:
```cpp
namespace {
static const QRegularExpression kMemRx{
R"((\d+(?:\.\d+)?)\s*\(?(MB|GB|KB|B)\)?)",
QRegularExpression::CaseInsensitiveOption
};
}
bool parseMemInfo(const QString& content, double& outValue, QString& outUnit) {
auto m = kMemRx.match(content);
if (!m.hasMatch()) {
qCritical() << "Error: no memory info in:" << content;
return false;
}
outValue = m.captured(1).toDouble();
outUnit = m.captured(2).toUpper();
return true;
}
```
3) replace the big `if/else` chain with a simple unit→factor map:
```cpp
static const QHash<QString,double> kUnitToGb {
{ "B", 1.0/(1024*1024*1024) },
{ "KB", 1.0/(1024*1024) },
{ "MB", 1.0/1024.0 },
{ "GB", 1.0 }
};
QString convertToGbString(double value, const QString& unit) {
double factor = kUnitToGb.value(unit, 0);
if (factor == 0) {
qCritical() << "Unknown unit:" << unit;
return {};
}
return QString::number(value * factor, 'f', 2) + "GB";
}
```
4) re-write `getGpuMemInfoForFTDTM()` as a simple orchestrator, and replace your manual loop in `getGpuInfoForFTDTM()` with a `join()`:
```cpp
bool DeviceInterface::getGpuMemInfoForFTDTM(QMap<QString,QString>& mapInfo) {
const QString c = readFileContent("/sys/kernel/debug/gc/total_mem");
if (c.isEmpty()) return false;
double value;
QString unit;
if (!parseMemInfo(c, value, unit)) return false;
const QString totalGb = convertToGbString(value, unit);
if (totalGb.isEmpty()) return false;
mapInfo.insert(kGraphicsMemory, totalGb);
return true;
}
QString DeviceInterface::getGpuInfoForFTDTM() {
static const QString info = []{
QMap<QString,QString> m;
if (!DeviceInterface{}.getGpuMemInfoForFTDTM(m))
return QString{};
QStringList lines;
for (auto it = m.constBegin(); it != m.constEnd(); ++it)
lines << QStringLiteral("%1: %2").arg(it.key(), it.value());
return lines.join(QLatin1Char('\n')) + QLatin1Char('\n');
}();
return info;
}
```
— now each helper does one job, the conversion is driven by a table instead of four branches, and your final formatting is a single `join()`.
</issue_to_address>
### Comment 2
<location> `deepin-devicemanager/src/Tool/commontools.cpp:269` </location>
<code_context>
QString CommonTools::preGenerateGpuInfo()
{
- static QString gpuInfo { "" };
</code_context>
<issue_to_address>
**issue (complexity):** Consider refactoring preGenerateGpuInfo() by extracting caching and formatting logic into helper functions for clarity and maintainability.
Here’s one way to split retrieval/formatting out and collapse the nested logic in preGenerateGpuInfo():
```cpp
// helper to format a map into “key: value\n…”
static QString formatInfoMap(const QMap<QString,QString>& m) {
QString s;
for (auto it = m.begin(); it != m.end(); ++it)
s += it.key() + ": " + it.value() + "\n";
return s;
}
// caches/returns GPU‐base info
static QString getCachedGpuBaseInfo() {
static QString base;
if (base.isEmpty()) {
QMap<QString,QString> m;
if (!CommonTools::getGpuBaseInfo(m)) {
qCritical() << "Error: failed to get gpu base info!";
return {};
}
base = formatInfoMap(m);
}
return base;
}
// caches/returns GPU‐mem info
static QString getCachedGpuMemInfo() {
static QString mem;
if (mem.isEmpty()) {
QDBusInterface iface("org.deepin.DeviceInfo",
"/org/deepin/DeviceInfo",
"org.deepin.DeviceInfo",
QDBusConnection::systemBus());
if (!iface.isValid()) {
qCritical() << "Error: GPU mem DBus interface invalid";
} else {
auto reply = iface.call("getGpuInfoForFTDTM");
if (reply.isValid()) mem = reply.value();
else qCritical() << "Error: failed to call getGpuInfoForFTDTM";
}
}
return mem;
}
// simplified preGenerateGpuInfo()
QString CommonTools::preGenerateGpuInfo() {
auto base = getCachedGpuBaseInfo();
if (base.isEmpty()) return {}; // already logged
return base + getCachedGpuMemInfo();
}
```
– Moves string‐building into formatInfoMap
– Moves each cache into its own function
– Makes preGenerateGpuInfo() a straight-line composition of those two calls
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| return result == Authority::Yes; | ||
| } | ||
|
|
||
| bool DeviceInterface::getGpuMemInfoForFTDTM(QMap<QString, QString> &mapInfo) |
There was a problem hiding this comment.
issue (complexity): Consider refactoring the method by extracting helpers, using a unit conversion map, and simplifying formatting with join().
Here are a few low-risk refactorings you can apply to keep the exact same behaviour but break that monster method into bite-sized helpers, remove the deep if/else, and collapse your formatting loop into a single join().
- pull the file-read and empty-check out into its own helper:
static QString readFileContent(const QString& path) {
QFile f(path);
if (!f.open(QIODevice::ReadOnly|QIODevice::Text)) {
qCritical() << "Error opening" << path << ":" << f.errorString();
return {};
}
return QString::fromUtf8(f.readAll()).trimmed();
}- pull the regex match into a helper + make the regex
static constso it isn’t reallocated every call:
namespace {
static const QRegularExpression kMemRx{
R"((\d+(?:\.\d+)?)\s*\(?(MB|GB|KB|B)\)?)",
QRegularExpression::CaseInsensitiveOption
};
}
bool parseMemInfo(const QString& content, double& outValue, QString& outUnit) {
auto m = kMemRx.match(content);
if (!m.hasMatch()) {
qCritical() << "Error: no memory info in:" << content;
return false;
}
outValue = m.captured(1).toDouble();
outUnit = m.captured(2).toUpper();
return true;
}- replace the big
if/elsechain with a simple unit→factor map:
static const QHash<QString,double> kUnitToGb {
{ "B", 1.0/(1024*1024*1024) },
{ "KB", 1.0/(1024*1024) },
{ "MB", 1.0/1024.0 },
{ "GB", 1.0 }
};
QString convertToGbString(double value, const QString& unit) {
double factor = kUnitToGb.value(unit, 0);
if (factor == 0) {
qCritical() << "Unknown unit:" << unit;
return {};
}
return QString::number(value * factor, 'f', 2) + "GB";
}- re-write
getGpuMemInfoForFTDTM()as a simple orchestrator, and replace your manual loop ingetGpuInfoForFTDTM()with ajoin():
bool DeviceInterface::getGpuMemInfoForFTDTM(QMap<QString,QString>& mapInfo) {
const QString c = readFileContent("/sys/kernel/debug/gc/total_mem");
if (c.isEmpty()) return false;
double value;
QString unit;
if (!parseMemInfo(c, value, unit)) return false;
const QString totalGb = convertToGbString(value, unit);
if (totalGb.isEmpty()) return false;
mapInfo.insert(kGraphicsMemory, totalGb);
return true;
}
QString DeviceInterface::getGpuInfoForFTDTM() {
static const QString info = []{
QMap<QString,QString> m;
if (!DeviceInterface{}.getGpuMemInfoForFTDTM(m))
return QString{};
QStringList lines;
for (auto it = m.constBegin(); it != m.constEnd(); ++it)
lines << QStringLiteral("%1: %2").arg(it.key(), it.value());
return lines.join(QLatin1Char('\n')) + QLatin1Char('\n');
}();
return info;
}— now each helper does one job, the conversion is driven by a table instead of four branches, and your final formatting is a single join().
| @@ -268,42 +268,40 @@ QString CommonTools::getGpuInfoCommandFromDConfig() | |||
|
|
|||
| QString CommonTools::preGenerateGpuInfo() | |||
There was a problem hiding this comment.
issue (complexity): Consider refactoring preGenerateGpuInfo() by extracting caching and formatting logic into helper functions for clarity and maintainability.
Here’s one way to split retrieval/formatting out and collapse the nested logic in preGenerateGpuInfo():
// helper to format a map into “key: value\n…”
static QString formatInfoMap(const QMap<QString,QString>& m) {
QString s;
for (auto it = m.begin(); it != m.end(); ++it)
s += it.key() + ": " + it.value() + "\n";
return s;
}
// caches/returns GPU‐base info
static QString getCachedGpuBaseInfo() {
static QString base;
if (base.isEmpty()) {
QMap<QString,QString> m;
if (!CommonTools::getGpuBaseInfo(m)) {
qCritical() << "Error: failed to get gpu base info!";
return {};
}
base = formatInfoMap(m);
}
return base;
}
// caches/returns GPU‐mem info
static QString getCachedGpuMemInfo() {
static QString mem;
if (mem.isEmpty()) {
QDBusInterface iface("org.deepin.DeviceInfo",
"/org/deepin/DeviceInfo",
"org.deepin.DeviceInfo",
QDBusConnection::systemBus());
if (!iface.isValid()) {
qCritical() << "Error: GPU mem DBus interface invalid";
} else {
auto reply = iface.call("getGpuInfoForFTDTM");
if (reply.isValid()) mem = reply.value();
else qCritical() << "Error: failed to call getGpuInfoForFTDTM";
}
}
return mem;
}
// simplified preGenerateGpuInfo()
QString CommonTools::preGenerateGpuInfo() {
auto base = getCachedGpuBaseInfo();
if (base.isEmpty()) return {}; // already logged
return base + getCachedGpuMemInfo();
}– Moves string‐building into formatInfoMap
– Moves each cache into its own function
– Makes preGenerateGpuInfo() a straight-line composition of those two calls
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: GongHeng2017, max-lvs The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
/forcemerge |
|
This pr force merged! (status: unstable) |
ee4e916
into
linuxdeepin:develop/eagle
-- Adjust code logic to show gpu mem.
Log: fix issue
Bug: https://pms.uniontech.com/bug-view-336355.html
Summary by Sourcery
Fix GPU memory display by implementing debugfs reading and parsing, refactor related GPU info retrieval methods, and clean up outdated command-based logic.
Bug Fixes:
Enhancements: