File indexing completed on 2024-05-12 17:00:15
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "LinuxNvidiaGpu.h" 0008 0009 #include <libudev.h> 0010 0011 NvidiaSmiProcess *LinuxNvidiaGpu::s_smiProcess = nullptr; 0012 0013 LinuxNvidiaGpu::LinuxNvidiaGpu(const QString &id, const QString &name, udev_device *device) 0014 : GpuDevice(id, name) 0015 , m_device(device) 0016 { 0017 if (!s_smiProcess) { 0018 s_smiProcess = new NvidiaSmiProcess(); 0019 } 0020 0021 connect(s_smiProcess, &NvidiaSmiProcess::dataReceived, this, &LinuxNvidiaGpu::onDataReceived); 0022 } 0023 0024 LinuxNvidiaGpu::~LinuxNvidiaGpu() 0025 { 0026 for (auto sensor : {m_usageProperty, m_totalVramProperty, m_usedVramProperty, m_temperatureProperty, m_coreFrequencyProperty, m_memoryFrequencyProperty}) { 0027 if (sensor->isSubscribed()) { 0028 LinuxNvidiaGpu::s_smiProcess->unref(); 0029 } 0030 } 0031 } 0032 0033 void LinuxNvidiaGpu::initialize() 0034 { 0035 GpuDevice::initialize(); 0036 0037 for (auto sensor : {m_usageProperty, 0038 m_totalVramProperty, 0039 m_usedVramProperty, 0040 m_temperatureProperty, 0041 m_coreFrequencyProperty, 0042 m_memoryFrequencyProperty, 0043 m_powerProperty}) { 0044 connect(sensor, &KSysGuard::SensorProperty::subscribedChanged, sensor, [sensor]() { 0045 if (sensor->isSubscribed()) { 0046 LinuxNvidiaGpu::s_smiProcess->ref(); 0047 } else { 0048 LinuxNvidiaGpu::s_smiProcess->unref(); 0049 } 0050 }); 0051 } 0052 0053 const auto queryResult = s_smiProcess->query(); 0054 const auto sysName = QString::fromLocal8Bit(udev_device_get_sysname(m_device)); 0055 auto it = std::find_if(queryResult.cbegin(), queryResult.cend(), [&sysName] (const NvidiaSmiProcess::GpuQueryResult &result) { 0056 return result.pciPath == sysName; 0057 }); 0058 if (it == queryResult.cend()) { 0059 qWarning() << "Could not retrieve information for NVidia GPU" << sysName; 0060 } else { 0061 m_index = it - queryResult.cbegin(); 0062 m_nameProperty->setValue(it->name); 0063 m_totalVramProperty->setValue(it->totalMemory); 0064 m_usedVramProperty->setMax(it->totalMemory); 0065 m_coreFrequencyProperty->setMax(it->maxCoreFrequency); 0066 m_memoryFrequencyProperty->setMax(it->maxMemoryFrequency); 0067 m_temperatureProperty->setMax(it->maxTemperature); 0068 m_powerProperty->setMax(it->maxPower); 0069 } 0070 0071 m_usedVramProperty->setUnit(KSysGuard::UnitMegaByte); 0072 m_totalVramProperty->setUnit(KSysGuard::UnitMegaByte); 0073 m_powerProperty->setUnit(KSysGuard::UnitWatt); 0074 } 0075 0076 void LinuxNvidiaGpu::onDataReceived(const NvidiaSmiProcess::GpuData &data) 0077 { 0078 if (data.index != m_index) { 0079 return; 0080 } 0081 0082 m_usageProperty->setValue(data.usage); 0083 m_usedVramProperty->setValue(data.memoryUsed); 0084 m_coreFrequencyProperty->setValue(data.coreFrequency); 0085 m_memoryFrequencyProperty->setValue(data.memoryFrequency); 0086 m_temperatureProperty->setValue(data.temperature); 0087 m_powerProperty->setValue(data.power); 0088 }