diff options
Diffstat (limited to 'device_info_procfs.c')
| -rw-r--r-- | device_info_procfs.c | 57 |
1 files changed, 16 insertions, 41 deletions
diff --git a/device_info_procfs.c b/device_info_procfs.c index 5ddf240..efef41a 100644 --- a/device_info_procfs.c +++ b/device_info_procfs.c | |||
| @@ -35,31 +35,24 @@ typedef struct { | |||
| 35 | 35 | ||
| 36 | //// ==v== PTOP_DEVICE_INFO ==v== //// | 36 | //// ==v== PTOP_DEVICE_INFO ==v== //// |
| 37 | 37 | ||
| 38 | static void* device_info_seq_start_backend(struct seq_file *s, loff_t *pos, int initial_entry_value, int total_entries) { | 38 | // Called to start or resume a sequence. Prior to 4.19, *pos is unreliable. |
| 39 | // Initializes iterator `idx` state and returns it. Ends sequence on NULL. | ||
| 40 | static void* device_info_file_seq_start(struct seq_file *s, loff_t *pos) { | ||
| 39 | static device_info_iter idx; | 41 | static device_info_iter idx; |
| 42 | struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)]; | ||
| 43 | int is_ampere = g->chip_id == NV_CHIP_ID_AMPERE; | ||
| 40 | // If start of sequence, reset `idx` | 44 | // If start of sequence, reset `idx` |
| 41 | if (*pos == 0) { | 45 | if (*pos == 0) { |
| 42 | idx.index = 0; | 46 | idx.index = 0; |
| 43 | idx.type_of_next_entry = initial_entry_value; | 47 | idx.type_of_next_entry = is_ampere ? 0 : -1; |
| 44 | } | 48 | } |
| 45 | idx.total_entries = total_entries; | 49 | idx.total_entries = is_ampere ? NV_PTOP_DEVICE_INFO__SIZE_1_PREVIOUS : NV_PTOP_DEVICE_INFO__SIZE_1_AMPERE(g); |
| 46 | // Number of possible info entries is fixed, and list is sparse | 50 | // Number of possible info entries is fixed, and list is sparse |
| 47 | if (idx.index >= idx.total_entries) | 51 | if (idx.index >= idx.total_entries) |
| 48 | return NULL; | 52 | return NULL; |
| 49 | return &idx; | 53 | return &idx; |
| 50 | } | 54 | } |
| 51 | 55 | ||
| 52 | // Called to start or resume a sequence. Prior to 4.19, *pos is unreliable. | ||
| 53 | // Initializes iterator `idx` state and returns it. Ends sequence on NULL. | ||
| 54 | static void* device_info_file_seq_start_previous(struct seq_file *s, loff_t *pos) { | ||
| 55 | return device_info_seq_start_backend(s, pos, -1, NV_PTOP_DEVICE_INFO__SIZE_1_PREVIOUS); | ||
| 56 | } | ||
| 57 | |||
| 58 | static void* device_info_file_seq_start_ampere(struct seq_file *s, loff_t *pos) { | ||
| 59 | struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)]; | ||
| 60 | return device_info_seq_start_backend(s, pos, 0, NV_PTOP_DEVICE_INFO__SIZE_1_AMPERE(g)); | ||
| 61 | } | ||
| 62 | |||
| 63 | // Steps to next record. Returns new value of `idx`. | 56 | // Steps to next record. Returns new value of `idx`. |
| 64 | // Calls show() on non-NULL return | 57 | // Calls show() on non-NULL return |
| 65 | static void* device_info_file_seq_next(struct seq_file *s, void *idx, | 58 | static void* device_info_file_seq_next(struct seq_file *s, void *idx, |
| @@ -166,43 +159,25 @@ static int device_info_file_seq_show_ampere(struct seq_file *s, void *idx) { | |||
| 166 | return 0; | 159 | return 0; |
| 167 | } | 160 | } |
| 168 | 161 | ||
| 169 | |||
| 170 | static void device_info_file_seq_stop(struct seq_file *s, void *idx) { | 162 | static void device_info_file_seq_stop(struct seq_file *s, void *idx) { |
| 171 | // No cleanup needed | 163 | // No cleanup needed |
| 172 | } | 164 | } |
| 173 | 165 | ||
| 174 | static const struct seq_operations device_info_file_seq_ops_previous = { | 166 | static struct seq_operations device_info_file_seq_ops = { |
| 175 | .start = device_info_file_seq_start_previous, | 167 | .start = device_info_file_seq_start, |
| 176 | .next = device_info_file_seq_next, | 168 | .next = device_info_file_seq_next, |
| 177 | .stop = device_info_file_seq_stop, | 169 | .stop = device_info_file_seq_stop |
| 178 | .show = device_info_file_seq_show_previous, | ||
| 179 | }; | ||
| 180 | |||
| 181 | static const struct seq_operations device_info_file_seq_ops_ampere = { | ||
| 182 | .start = device_info_file_seq_start_ampere, | ||
| 183 | .next = device_info_file_seq_next, | ||
| 184 | .stop = device_info_file_seq_stop, | ||
| 185 | .show = device_info_file_seq_show_ampere, | ||
| 186 | }; | 170 | }; |
| 187 | 171 | ||
| 188 | static int device_info_file_open_previous(struct inode *inode, struct file *f) { | 172 | static int device_info_file_open(struct inode *inode, struct file *f) { |
| 189 | return seq_open(f, &device_info_file_seq_ops_previous); | 173 | struct seq_operations file_seq_ops = device_info_file_seq_ops; |
| 174 | file_seq_ops.show = (g_nvdebug_state[file2parentgpuidx(f)].chip_id == NV_CHIP_ID_AMPERE) ? device_info_file_seq_show_ampere : device_info_file_seq_show_previous; | ||
| 175 | return seq_open(f, &file_seq_ops); | ||
| 190 | } | 176 | } |
| 191 | 177 | ||
| 192 | static int device_info_file_open_ampere(struct inode *inode, struct file *f) { | 178 | struct file_operations device_info_file_ops = { |
| 193 | return seq_open(f, &device_info_file_seq_ops_ampere); | 179 | .open = device_info_file_open, |
| 194 | } | ||
| 195 | |||
| 196 | struct file_operations device_info_file_ops_previous = { | ||
| 197 | .open = device_info_file_open_previous, | ||
| 198 | .read = seq_read, | 180 | .read = seq_read, |
| 199 | .llseek = seq_lseek, | 181 | .llseek = seq_lseek, |
| 200 | .release = seq_release, | 182 | .release = seq_release, |
| 201 | }; | 183 | }; |
| 202 | |||
| 203 | struct file_operations device_info_file_ops_ampere = { | ||
| 204 | .open = device_info_file_open_ampere, | ||
| 205 | .read = seq_read, | ||
| 206 | .llseek = seq_lseek, | ||
| 207 | .release = seq_release, | ||
| 208 | }; | ||
