@@ -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