File indexing completed on 2024-05-19 05:30:19
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 constexpr quint64 mbToBytes(quint64 mb) { 0014 return mb * 1024 * 1024; 0015 } 0016 0017 LinuxNvidiaGpu::LinuxNvidiaGpu(const QString &id, const QString &name, udev_device *device) 0018 : GpuDevice(id, name) 0019 , m_device(device) 0020 { 0021 if (!s_smiProcess) { 0022 s_smiProcess = new NvidiaSmiProcess(); 0023 } 0024 0025 connect(s_smiProcess, &NvidiaSmiProcess::dataReceived, this, &LinuxNvidiaGpu::onDataReceived); 0026 } 0027 0028 LinuxNvidiaGpu::~LinuxNvidiaGpu() 0029 { 0030 for (auto sensor : {m_usageProperty, m_totalVramProperty, m_usedVramProperty, m_temperatureProperty, m_coreFrequencyProperty, m_memoryFrequencyProperty}) { 0031 if (sensor->isSubscribed()) { 0032 LinuxNvidiaGpu::s_smiProcess->unref(); 0033 } 0034 } 0035 } 0036 0037 void LinuxNvidiaGpu::initialize() 0038 { 0039 GpuDevice::initialize(); 0040 0041 for (auto sensor : {m_usageProperty, 0042 m_totalVramProperty, 0043 m_usedVramProperty, 0044 m_temperatureProperty, 0045 m_coreFrequencyProperty, 0046 m_memoryFrequencyProperty, 0047 m_powerProperty}) { 0048 connect(sensor, &KSysGuard::SensorProperty::subscribedChanged, sensor, [sensor]() { 0049 if (sensor->isSubscribed()) { 0050 LinuxNvidiaGpu::s_smiProcess->ref(); 0051 } else { 0052 LinuxNvidiaGpu::s_smiProcess->unref(); 0053 } 0054 }); 0055 } 0056 0057 const auto queryResult = s_smiProcess->query(); 0058 const auto sysName = QString::fromLocal8Bit(udev_device_get_sysname(m_device)); 0059 auto it = std::find_if(queryResult.cbegin(), queryResult.cend(), [&sysName] (const NvidiaSmiProcess::GpuQueryResult &result) { 0060 return result.pciPath == sysName; 0061 }); 0062 if (it == queryResult.cend()) { 0063 qWarning() << "Could not retrieve information for NVidia GPU" << sysName; 0064 } else { 0065 m_index = it - queryResult.cbegin(); 0066 m_nameProperty->setValue(it->name); 0067 m_totalVramProperty->setValue(mbToBytes(it->totalMemory)); 0068 m_usedVramProperty->setMax(mbToBytes(it->totalMemory)); 0069 m_coreFrequencyProperty->setMax(it->maxCoreFrequency); 0070 m_memoryFrequencyProperty->setMax(it->maxMemoryFrequency); 0071 m_temperatureProperty->setMax(it->maxTemperature); 0072 m_powerProperty->setMax(it->maxPower); 0073 } 0074 0075 m_powerProperty->setUnit(KSysGuard::UnitWatt); 0076 } 0077 0078 void LinuxNvidiaGpu::onDataReceived(const NvidiaSmiProcess::GpuData &data) 0079 { 0080 if (data.index != m_index) { 0081 return; 0082 } 0083 0084 m_usageProperty->setValue(data.usage); 0085 m_usedVramProperty->setValue(mbToBytes(data.memoryUsed)); 0086 m_coreFrequencyProperty->setValue(data.coreFrequency); 0087 m_memoryFrequencyProperty->setValue(data.memoryFrequency); 0088 m_temperatureProperty->setValue(data.temperature); 0089 m_powerProperty->setValue(data.power); 0090 } 0091 0092 #include "moc_LinuxNvidiaGpu.cpp"