36
38
static void probe_displays_received(GtkObject *object, gpointer arg1,
37
39
gpointer user_data);
38
static gboolean update_gpu_memory_used(gpointer);
40
static gboolean update_gpu_usage(gpointer);
40
42
#define ARRAY_ELEMENTS 16
41
43
#define DEFAULT_UPDATE_GPU_INFO_TIME_INTERVAL 3000
49
} utilizationEntry, * utilizationEntryPtr;
43
51
GType ctk_gpu_get_type(
136
void get_bus_id_str(NvCtrlAttributeHandle *handle,
144
gchar *get_bus_id_str(NvCtrlAttributeHandle *handle)
140
147
int pci_domain, pci_bus, pci_device, pci_func;
142
const gchar *__pci_bus_id_unknown = "?@?:?:?";
144
150
/* NV_CTRL_PCI_DOMAIN & NV_CTRL_PCI_BUS &
145
151
* NV_CTRL_PCI_DEVICE & NV__CTRL_PCI_FUNCTION
149
154
ret = NvCtrlGetAttribute(handle, NV_CTRL_PCI_DOMAIN, &pci_domain);
150
if (ret != NvCtrlSuccess) goto bus_id_fallback;
155
if (ret != NvCtrlSuccess) {
152
159
ret = NvCtrlGetAttribute(handle, NV_CTRL_PCI_BUS, &pci_bus);
153
if (ret != NvCtrlSuccess) goto bus_id_fallback;
160
if (ret != NvCtrlSuccess) {
155
164
ret = NvCtrlGetAttribute(handle, NV_CTRL_PCI_DEVICE, &pci_device);
156
if (ret != NvCtrlSuccess) goto bus_id_fallback;
165
if (ret != NvCtrlSuccess) {
158
169
ret = NvCtrlGetAttribute(handle, NV_CTRL_PCI_FUNCTION, &pci_func);
159
if (ret != NvCtrlSuccess) goto bus_id_fallback;
163
xconfigFormatPciBusString(bus_id, 32, pci_domain, pci_bus,
164
pci_device, pci_func);
170
if (ret != NvCtrlSuccess) {
174
bus_id = g_malloc(32);
170
bus_id = g_strdup(__pci_bus_id_unknown);
173
*pci_bus_id = bus_id;
178
xconfigFormatPciBusString(bus_id, 32, pci_domain, pci_bus,
179
pci_device, pci_func);
238
246
ret = NvCtrlGetStringAttribute(handle, NV_CTRL_STRING_PRODUCT_NAME,
240
if (ret != NvCtrlSuccess) product_name = NULL;
248
if (ret != NvCtrlSuccess) {
252
ret = NvCtrlGetStringAttribute(handle, NV_CTRL_STRING_GPU_UUID,
254
if (ret != NvCtrlSuccess) {
242
258
/* Get Bus related information */
244
get_bus_id_str(handle, &pci_bus_id);
260
pci_bus_id = get_bus_id_str(handle);
246
262
/* NV_CTRL_PCI_ID */
248
pci_device_id[ARRAY_ELEMENTS-1] = '\0';
249
pci_vendor_id[ARRAY_ELEMENTS-1] = '\0';
264
memset(&pci_device_id, 0, sizeof(pci_device_id));
265
memset(&pci_vendor_id, 0, sizeof(pci_vendor_id));
251
267
ret = NvCtrlGetAttribute(handle, NV_CTRL_PCI_ID, &pci_id);
253
if (ret != NvCtrlSuccess) {
254
snprintf(pci_device_id, ARRAY_ELEMENTS, "Unknown");
255
snprintf(pci_vendor_id, ARRAY_ELEMENTS, "Unknown");
269
if (ret == NvCtrlSuccess) {
257
270
snprintf(pci_device_id, ARRAY_ELEMENTS, "0x%04x", (pci_id & 0xFFFF));
258
271
snprintf(pci_vendor_id, ARRAY_ELEMENTS, "0x%04x", (pci_id >> 16));
429
443
add_table_row(table, row++,
430
444
0, 0.5, "Graphics Processor:",
431
445
0, 0.5, product_name);
446
if ( ctk_gpu->gpu_uuid ) {
447
add_table_row(table, row++,
432
451
if ( ctk_gpu->gpu_cores ) {
433
452
gtk_table_resize(GTK_TABLE(table), ++total_rows, 2);
434
453
add_table_row(table, row++,
435
454
0, 0.5, "CUDA Cores:",
436
455
0, 0.5, gpu_cores);
438
add_table_row(table, row++,
439
0, 0.5, "VBIOS Version:",
440
0, 0.5, vbios_version);
457
if ( vbios_version ) {
458
add_table_row(table, row++,
459
0, 0.5, "VBIOS Version:",
460
0, 0.5, vbios_version);
441
462
add_table_row(table, row++,
442
463
0, 0.5, "Total Memory:",
443
464
0, 0.5, video_ram);
448
469
add_table_row(table, row++,
449
470
0, 0.5, "Used Dedicated Memory:",
451
update_gpu_memory_used(ctk_gpu);
452
472
if ( ctk_gpu->memory_interface ) {
453
473
gtk_table_resize(GTK_TABLE(table), ++total_rows, 2);
454
474
add_table_row(table, row++,
455
475
0, 0.5, "Memory Interface:",
456
476
0, 0.5, memory_interface);
478
ctk_gpu->gpu_utilization_label =
479
add_table_row(table, row++,
480
0, 0.5, "GPU Utilization:",
482
ctk_gpu->video_utilization_label =
483
add_table_row(table, row++,
484
0, 0.5, "Video Engine Utilization:",
460
488
add_table_row(table, row++,
461
489
0, 0.5, "Bus Type:",
463
add_table_row(table, row++,
466
add_table_row(table, row++,
467
0, 0.5, "PCI Device ID:",
468
0, 0.5, pci_device_id);
469
add_table_row(table, row++,
470
0, 0.5, "PCI Vendor ID:",
471
0, 0.5, pci_vendor_id);
472
add_table_row(table, row++,
492
add_table_row(table, row++,
496
if ( pci_device_id[0] ) {
497
add_table_row(table, row++,
498
0, 0.5, "PCI Device ID:",
499
0, 0.5, pci_device_id);
501
if (pci_vendor_id[0] ) {
502
add_table_row(table, row++,
503
0, 0.5, "PCI Vendor ID:",
504
0, 0.5, pci_vendor_id);
507
add_table_row(table, row++,
475
511
if (ctk_gpu->pcie_gen_queriable) {
484
520
add_table_row(table, row++,
485
521
0, 0.5, "Maximum PCIe Link Speed:",
486
522
0, 0.5, link_speed_str);
523
ctk_gpu->pcie_utilization_label =
524
add_table_row(table, row++,
525
0, 0.5, "PCIe Bandwidth Utilization:",
487
528
g_free(link_speed_str);
488
529
g_free(link_width_str);
489
530
g_free(pcie_gen_str);
534
update_gpu_usage(ctk_gpu);
495
537
add_table_row(table, row++,
559
601
ctk_help_heading(b, &i, "Graphics Processor");
560
602
ctk_help_para(b, &i, "This is the product name of the GPU.");
604
if (ctk_gpu->gpu_uuid) {
605
ctk_help_heading(b, &i, "GPU UUID");
606
ctk_help_para(b, &i, "This is the global unique identifier "
562
610
if (ctk_gpu->gpu_cores) {
563
611
ctk_help_heading(b, &i, "CUDA Cores");
564
612
ctk_help_para(b, &i, "This is the number of CUDA cores supported by "
591
639
"memory interface.");
642
ctk_help_heading(b, &i, "GPU Utilization");
643
ctk_help_para(b, &i, "This is the percentage usage of graphics engine.");
645
ctk_help_heading(b, &i, "Video Engine Utilization");
646
ctk_help_para(b, &i, "This is the percentage usage of video engine");
594
648
ctk_help_heading(b, &i, "Bus Type");
595
649
ctk_help_para(b, &i, "This is the bus type which is "
596
650
"used to connect the NVIDIA GPU to the rest of "
602
656
"in X configuration file 'BusID' format: "
603
657
"\"bus:device:function\", or, if the PCI domain of the GPU "
604
658
"is non-zero, \"bus@domain:device:function\". Note "
605
"that all values are in decimal (as opposed to hexidecimal, "
659
"that all values are in decimal (as opposed to hexadecimal, "
606
660
"which is how `lspci` formats its BusID values).");
608
662
ctk_help_heading(b, &i, "PCI Device ID");
634
688
"This is expressed in gigatransfers per second "
635
689
"(GT/s). The link may be dynamically trained to a "
636
690
"slower speed, based on the GPU's utilization and "
637
"performance settings.");
691
"performance settings.");
693
ctk_help_heading(b, &i, "PCIe Bandwidth Utilization");
694
ctk_help_para(b, &i, "This is the percentage usage of "
640
699
ctk_help_heading(b, &i, "X Screens");
667
static gboolean update_gpu_memory_used(gpointer user_data)
728
static void apply_gpu_utilization_token(char *token, char *value, void *data)
730
utilizationEntryPtr pEntry = (utilizationEntryPtr) data;
732
if (!strcasecmp("graphics", token)) {
733
pEntry->graphics = atoi(value);
734
} else if (!strcasecmp("video", token)) {
735
pEntry->video = atoi(value);
736
} else if (!strcasecmp("pcie", token)) {
737
pEntry->pcie = atoi(value);
739
nv_warning_msg("Unknown GPU utilization token value pair: %s=%s",
746
static gboolean update_gpu_usage(gpointer user_data)
670
749
gchar *memory_text;
750
gchar *utilization_text = NULL;
671
751
ReturnStatus ret;
673
static int num_failures = 0;
752
gchar *utilizationStr = NULL;
754
utilizationEntry entry;
675
756
ctk_gpu = CTK_GPU(user_data);
696
775
g_free(memory_text);
778
/* GPU utilization */
779
ret = NvCtrlGetStringAttribute(ctk_gpu->handle,
780
NV_CTRL_STRING_GPU_UTILIZATION,
782
if (ret != NvCtrlSuccess) {
783
gtk_label_set_text(GTK_LABEL(ctk_gpu->gpu_utilization_label), "Unknown");
784
gtk_label_set_text(GTK_LABEL(ctk_gpu->video_utilization_label),
786
if (ctk_gpu->pcie_utilization_label) {
787
gtk_label_set_text(GTK_LABEL(ctk_gpu->pcie_utilization_label),
792
memset(&entry, -1, sizeof(&entry));
793
parse_token_value_pairs(utilizationStr, apply_gpu_utilization_token,
795
if (entry.graphics != -1) {
796
utilization_text = g_strdup_printf("%d %%",
799
gtk_label_set_text(GTK_LABEL(ctk_gpu->gpu_utilization_label),
802
if (entry.video != -1) {
803
utilization_text = g_strdup_printf("%d %%",
806
gtk_label_set_text(GTK_LABEL(ctk_gpu->video_utilization_label),
809
if ((entry.pcie != -1) &&
810
(ctk_gpu->pcie_utilization_label)) {
811
utilization_text = g_strdup_printf("%d %%",
814
gtk_label_set_text(GTK_LABEL(ctk_gpu->pcie_utilization_label),
817
g_free(utilization_text);
704
824
CtkGpu *ctk_gpu = CTK_GPU(widget);
826
/* Update GPU usage */
828
update_gpu_usage(ctk_gpu);
706
830
/* Start the gpu timer */
708
832
ctk_config_start_timer(ctk_gpu->ctk_config,
709
(GSourceFunc) update_gpu_memory_used,
833
(GSourceFunc) update_gpu_usage,
710
834
(gpointer) ctk_gpu);