-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathutils.h
More file actions
142 lines (115 loc) · 2.85 KB
/
Copy pathutils.h
File metadata and controls
142 lines (115 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef UTILS_H
#define UTILS_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <limits.h> // PATH_MAX
#define UVM_IS_INITIALIZED 80
typedef struct
{
CUuuid uuid; // IN
bool initialized; // OUT
int rmStatus; // OUT
} UVM_IS_INITIALIZED_PARAMS;
typedef enum
{
UVM_SUBMIT_KERNEL_EVENT = 0,
UVM_END_KERNEL_EVENT,
UVM_EVENT_TYPE_COUNT
} UVM_EVENT_TYPE;
typedef enum {
UVM_ADD_EVENT_COUNT = 0,
UVM_SET_EVENT_COUNT,
UVM_UPDATE_EVENT_COUNT_TYPE_COUNT
} UVM_UPDATE_EVENT_COUNT_TYPE;
#define UVM_UPDATE_EVENT_COUNT 81
typedef struct
{
CUuuid uuid;
UVM_EVENT_TYPE type;
UVM_UPDATE_EVENT_COUNT_TYPE op;
uint64_t value;
int rmStatus;
} UVM_UPDATE_EVENT_COUNT_PARAMS;
static int find_initialized_uvm(CUuuid uuid)
{
pid_t pid = getpid();
char fd_dir[64];
const char *target_path = "/dev/nvidia-uvm";
int ret = -1;
snprintf(fd_dir, sizeof(fd_dir), "/proc/%d/fd", (int)pid);
DIR *dir = opendir(fd_dir);
if (!dir) {
fprintf(stderr, "Failed to open %s: %s\n", fd_dir, strerror(errno));
return ret;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
char link_path[PATH_MAX];
char fd_path[PATH_MAX];
ssize_t len;
int fd;
// Skip "." and ".."
if (entry->d_name[0] == '.' &&
(entry->d_name[1] == '\0' ||
(entry->d_name[1] == '.' && entry->d_name[2] == '\0'))) {
continue;
}
// /proc/<pid>/fd/<fd>
snprintf(link_path, sizeof(link_path), "%s/%s", fd_dir, entry->d_name);
len = readlink(link_path, fd_path, sizeof(fd_path) - 1);
if (len < 0) {
// could log if you care; original code just continued on error_code
continue;
}
fd_path[len] = '\0';
if (strcmp(fd_path, target_path) != 0)
continue;
fd = atoi(entry->d_name);
if (fd < 0) {
fprintf(stderr, "Invalid file descriptor: %d\n", fd);
continue;
}
UVM_IS_INITIALIZED_PARAMS params = {
.uuid = uuid,
.initialized = 0,
.rmStatus = 0
};
if (ioctl(fd, UVM_IS_INITIALIZED, ¶ms) == 0 && params.rmStatus == 0) {
if (params.initialized) {
ret = fd;
break;
}
} else {
fprintf(stderr, "Failed to check UVM initialization on fd %d: %s\n",
fd, strerror(errno));
}
}
closedir(dir);
return ret;
}
static int update_event_count(int uvmfd, CUuuid uuid, UVM_EVENT_TYPE type, UVM_UPDATE_EVENT_COUNT_TYPE op, uint64_t value) {
int ret = 0;
UVM_UPDATE_EVENT_COUNT_PARAMS params = {
.uuid = uuid,
.type = type,
.op = op,
.value = value,
.rmStatus = 0
};
if ((ret = ioctl(uvmfd, UVM_UPDATE_EVENT_COUNT, ¶ms)) != 0)
return ret;
if (params.rmStatus != 0)
fprintf(stderr, "uvm_ioctl: error code %d\n", params.rmStatus);
return 0;
}
static size_t gettime_ms(void) {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return (size_t)(ts.tv_sec) * 1000 + (ts.tv_nsec) / 1000000;
}
#endif