Skip to content

Commit d955f94

Browse files
committed
Fix unified memory reporting to use MemAvailable
Use /proc/meminfo MemAvailable instead of sysinfo freeram to properly account for reclaimable cache. Now matches free -h output accurately.
1 parent 339ee0b commit d955f94

File tree

1 file changed

+59
-10
lines changed

1 file changed

+59
-10
lines changed

src/extract_gpuinfo_nvidia.c

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -607,26 +607,75 @@ static void gpuinfo_nvidia_refresh_dynamic_info(struct gpu_info *_gpu_info) {
607607

608608
// Device memory info (total,used,free)
609609
bool got_meminfo = false;
610+
bool has_unified_memory = false;
611+
610612
if (nvmlDeviceGetMemoryInfo_v2) {
611613
nvmlMemory_v2_t memory_info;
612614
memory_info.version = 2;
613615
last_nvml_return_status = nvmlDeviceGetMemoryInfo_v2(device, &memory_info);
614616
if (last_nvml_return_status == NVML_SUCCESS) {
615-
got_meminfo = true;
616-
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, memory_info.total);
617-
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, memory_info.used);
618-
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, memory_info.free);
619-
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, memory_info.used * 100 / memory_info.total);
617+
// Check if this is a unified memory GPU (total == 0 indicates unified memory)
618+
if (memory_info.total == 0) {
619+
has_unified_memory = true;
620+
} else {
621+
got_meminfo = true;
622+
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, memory_info.total);
623+
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, memory_info.used);
624+
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, memory_info.free);
625+
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, memory_info.used * 100 / memory_info.total);
626+
}
627+
} else {
628+
// Memory query failed - likely unified memory GPU (error code 13 = NOT_SUPPORTED)
629+
has_unified_memory = true;
620630
}
621631
}
622-
if (!got_meminfo && nvmlDeviceGetMemoryInfo) {
632+
if (!got_meminfo && !has_unified_memory && nvmlDeviceGetMemoryInfo) {
623633
nvmlMemory_v1_t memory_info;
624634
last_nvml_return_status = nvmlDeviceGetMemoryInfo(device, &memory_info);
625635
if (last_nvml_return_status == NVML_SUCCESS) {
626-
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, memory_info.total);
627-
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, memory_info.used);
628-
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, memory_info.free);
629-
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, memory_info.used * 100 / memory_info.total);
636+
// Check if this is a unified memory GPU (total == 0 indicates unified memory)
637+
if (memory_info.total == 0) {
638+
has_unified_memory = true;
639+
} else {
640+
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, memory_info.total);
641+
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, memory_info.used);
642+
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, memory_info.free);
643+
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, memory_info.used * 100 / memory_info.total);
644+
}
645+
} else {
646+
// Memory query failed - likely unified memory GPU
647+
has_unified_memory = true;
648+
}
649+
}
650+
651+
// Handle unified memory GPUs - query system memory instead
652+
if (has_unified_memory) {
653+
// Read MemAvailable from /proc/meminfo for accurate available memory
654+
// This matches what 'free -h' reports and includes reclaimable cache
655+
FILE *meminfo = fopen("/proc/meminfo", "r");
656+
if (meminfo) {
657+
unsigned long long total_ram = 0;
658+
unsigned long long available_ram = 0;
659+
char line[256];
660+
661+
while (fgets(line, sizeof(line), meminfo)) {
662+
if (sscanf(line, "MemTotal: %llu kB", &total_ram) == 1) {
663+
total_ram *= 1024; // Convert KB to bytes
664+
} else if (sscanf(line, "MemAvailable: %llu kB", &available_ram) == 1) {
665+
available_ram *= 1024; // Convert KB to bytes
666+
break; // We have both values, can stop reading
667+
}
668+
}
669+
fclose(meminfo);
670+
671+
if (total_ram > 0 && available_ram > 0) {
672+
unsigned long long used_ram = total_ram - available_ram;
673+
674+
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, total_ram);
675+
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, used_ram);
676+
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, available_ram);
677+
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, used_ram * 100 / total_ram);
678+
}
630679
}
631680
}
632681

0 commit comments

Comments
 (0)