Updated `README.md` with instructions for building/using the kernel module.
[xeon-phi-kernel-module] / micscif / micscif_debug.c
CommitLineData
800f879a
AT
1/*
2 * Copyright 2010-2017 Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 *
13 * Disclaimer: The codes contained in these modules may be specific to
14 * the Intel Software Development Platform codenamed Knights Ferry,
15 * and the Intel product codenamed Knights Corner, and are not backward
16 * compatible with other Intel products. Additionally, Intel will NOT
17 * support the codes or instruction set in future products.
18 *
19 * Intel offers no warranty of any kind regarding the code. This code is
20 * licensed on an "AS IS" basis and Intel is not obligated to provide
21 * any support, assistance, installation, training, or other services
22 * of any kind. Intel is also not obligated to provide any updates,
23 * enhancements or extensions. Intel specifically disclaims any warranty
24 * of merchantability, non-infringement, fitness for any particular
25 * purpose, and any other warranty.
26 *
27 * Further, Intel disclaims all liability of any kind, including but
28 * not limited to liability for infringement of any proprietary rights,
29 * relating to the use of the code, even if Intel is notified of the
30 * possibility of such liability. Except as expressly stated in an Intel
31 * license agreement provided with this code and agreed upon with Intel,
32 * no license, express or implied, by estoppel or otherwise, to any
33 * intellectual property rights is granted herein.
34 */
35
36#include "mic/micscif.h"
37#ifndef _MIC_SCIF_
38#include "mic_common.h"
39#endif
40#include "scif.h"
41#include <linux/proc_fs.h>
42#include <linux/debugfs.h>
43
44#include <linux/module.h>
45
46static char *window_type[] = {
47 "NONE",
48 "SELF",
49 "PEER"};
50
51static char *scifdev_state[] = {
52 "SCIFDEV_NOTPRESENT",
53 "SCIFDEV_INIT",
54 "SCIFDEV_RUNNING",
55 "SCIFDEV_SLEEPING",
56 "SCIFDEV_STOPPING",
57 "SCIFDEV_STOPPED"};
58
59static struct proc_dir_entry *scif_proc;
60static struct dentry *mic_debug = NULL;
61
62#define DEBUG_LEN 10
63
64static int
65scif_ep_show(struct seq_file *m, void *data)
66{
67 struct endpt *ep;
68 struct list_head *pos;
69 unsigned long sflags;
70
71 seq_printf(m, "EP Address State Port Peer Remote Ep Address\n");
72 seq_printf(m, "=================================================================\n");
73 spin_lock_irqsave(&ms_info.mi_eplock, sflags);
74 list_for_each(pos, &ms_info.mi_listen) {
75 ep = list_entry(pos, struct endpt, list);
76 seq_printf(m, "%p %s %6d\n",
77 ep, scif_ep_states[ep->state], ep->port.port);
78 }
79 spin_unlock_irqrestore(&ms_info.mi_eplock, sflags);
80
81 spin_lock_irqsave(&ms_info.mi_connlock, sflags);
82 list_for_each(pos, &ms_info.mi_connected) {
83 ep = list_entry(pos, struct endpt, list);
84 seq_printf(m, "%p %s %6d %2d:%-6d %p\n",
85 ep, scif_ep_states[ep->state], ep->port.port, ep->peer.node,
86 ep->peer.port, (void *)ep->remote_ep);
87 }
88 list_for_each(pos, &ms_info.mi_disconnected) {
89 ep = list_entry(pos, struct endpt, list);
90 seq_printf(m, "%p %s %6d %2d:%-6d %p\n",
91 ep, scif_ep_states[ep->state], ep->port.port, ep->peer.node,
92 ep->peer.port, (void *)ep->remote_ep);
93 }
94 spin_unlock_irqrestore(&ms_info.mi_connlock, sflags);
95
96 seq_printf(m, "EP Address State Port Peer Remote Ep Address reg_list "
97 "remote_reg_list mmn_list tw_refcount tcw_refcount mi_rma mi_rma_tc "
98 "task_list mic_mmu_notif_cleanup\n");
99 seq_printf(m, "=================================================================\n");
100 spin_lock_irqsave(&ms_info.mi_eplock, sflags);
101 list_for_each(pos, &ms_info.mi_zombie) {
102 ep = list_entry(pos, struct endpt, list);
103 seq_printf(m, "%p %s %6d %2d:%-6d %p %d %d %d %d %d %d %d %d %d\n",
104 ep, scif_ep_states[ep->state], ep->port.port, ep->peer.node,
105 ep->peer.port, (void *)ep->remote_ep,
106 list_empty(&ep->rma_info.reg_list),
107 list_empty(&ep->rma_info.remote_reg_list),
108 list_empty(&ep->rma_info.mmn_list),
109 atomic_read(&ep->rma_info.tw_refcount),
110 atomic_read(&ep->rma_info.tcw_refcount),
111 list_empty(&ms_info.mi_rma),
112 list_empty(&ms_info.mi_rma_tc),
113 list_empty(&ep->rma_info.task_list),
114#ifdef CONFIG_MMU_NOTIFIER
115 list_empty(&ms_info.mi_mmu_notif_cleanup)
116#else
117 -1
118#endif
119 );
120 }
121 spin_unlock_irqrestore(&ms_info.mi_eplock, sflags);
122
123 return 0;
124}
125
126static int
127scif_ep_open(struct inode *inode, struct file *file)
128{
129 return single_open(file, scif_ep_show, NULL);
130}
131
132struct file_operations scif_ep_fops = {
133 .open = scif_ep_open,
134 .read = seq_read,
135 .llseek = seq_lseek,
136 .release = single_release,
137};
138
139#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
140
141static int
142scif_rma_window_show(struct seq_file *m, void *data)
143{
144 struct endpt *ep;
145 struct list_head *pos, *item, *tmp;
146 unsigned long sflags;
147 struct reg_range_t *window;
148
149 seq_printf(m, "SCIF Connected EP RMA Window Info\n");
150 seq_printf(m, "=================================================================\n");
151 seq_printf(m, "%-16s\t%-16s %-16s %-16s %-8s %-8s %-8s\n",
152 "Endpoint", "Type", "Offset", "NumPages", "Prot", "Ref_Count", "Unreg State");
153 spin_lock_irqsave(&ms_info.mi_connlock, sflags);
154 list_for_each(pos, &ms_info.mi_connected) {
155 ep = list_entry(pos, struct endpt, list);
156 if (mutex_trylock(&ep->rma_info.rma_lock)) {
157 list_for_each_safe(item, tmp, &ep->rma_info.reg_list) {
158 window = list_entry(item, struct reg_range_t, list_member);
159 seq_printf(m,
160 "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
161 ep, window_type[window->type], window->offset,
162 window->nr_pages, window->prot, window->ref_count,
163 window->unreg_state);
164 }
165 list_for_each_safe(item, tmp, &ep->rma_info.remote_reg_list) {
166 window = list_entry(item, struct reg_range_t, list_member);
167 seq_printf(m,
168 "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
169 ep, window_type[window->type], window->offset,
170 window->nr_pages, window->prot, window->ref_count,
171 window->unreg_state);
172 }
173 mutex_unlock(&ep->rma_info.rma_lock);
174 } else
175 seq_printf(m,
176 "Try Again, some other thread has the RMA lock for ep %p\n",
177 ep);
178 }
179 spin_unlock_irqrestore(&ms_info.mi_connlock, sflags);
180
181 seq_printf(m, "=================================================================\n");
182 seq_printf(m, "SCIF Zombie EP RMA Window Info\n");
183 spin_lock_irqsave(&ms_info.mi_eplock, sflags);
184 list_for_each(pos, &ms_info.mi_zombie) {
185 ep = list_entry(pos, struct endpt, list);
186 if (mutex_trylock(&ep->rma_info.rma_lock)) {
187 list_for_each_safe(item, tmp, &ep->rma_info.reg_list) {
188 window = list_entry(item, struct reg_range_t, list_member);
189 seq_printf(m,
190 "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
191 ep, window_type[window->type], window->offset,
192 window->nr_pages, window->prot, window->ref_count,
193 window->unreg_state);
194 }
195 list_for_each_safe(item, tmp, &ep->rma_info.remote_reg_list) {
196 window = list_entry(item, struct reg_range_t, list_member);
197 seq_printf(m,
198 "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
199 ep, window_type[window->type], window->offset,
200 window->nr_pages, window->prot, window->ref_count,
201 window->unreg_state);
202 }
203 mutex_unlock(&ep->rma_info.rma_lock);
204 } else
205 seq_printf(m,
206 "Try Again, some other thread has the RMA lock for ep %p\n",
207 ep);
208 }
209 spin_unlock_irqrestore(&ms_info.mi_eplock, sflags);
210 seq_printf(m, "=================================================================\n");
211 seq_printf(m, "%-16s\t%-16s %-16s %-16s %-8s %-8s %-8s\n",
212 "Endpoint", "Type", "Offset", "NumPages", "Prot", "Ref_Count", "Unreg State");
213 spin_lock(&ms_info.mi_rmalock);
214 list_for_each_safe(item, tmp, &ms_info.mi_rma) {
215 window = list_entry(item,
216 struct reg_range_t, list_member);
217 ep = (struct endpt *)window->ep;
218 seq_printf(m, "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
219 ep, window_type[window->type], window->offset,
220 window->nr_pages, window->prot, window->ref_count,
221 window->unreg_state);
222 }
223 spin_unlock(&ms_info.mi_rmalock);
224
225 return 0;
226}
227
228static int
229scif_rma_window_open(struct inode *inode, struct file *file)
230{
231 return single_open(file, scif_rma_window_show, NULL);
232}
233
234struct file_operations scif_rma_window_fops = {
235 .open = scif_rma_window_open,
236 .read = seq_read,
237 .llseek = seq_lseek,
238 .release = single_release,
239};
240
241static int
242scif_rma_xfer_show(struct seq_file *m, void *data)
243{
244 struct endpt *ep;
245 struct list_head *pos;
246 unsigned long sflags;
247
248 seq_printf(m, "SCIF RMA Debug\n");
249 seq_printf(m, "=================================================================\n");
250 seq_printf(m, "%-16s\t %-16s %-16s %-16s\n",
251 "Endpoint", "Fence Ref Count", "Temp Window Ref Count", "DMA CHANNEL");
252 spin_lock_irqsave(&ms_info.mi_connlock, sflags);
253 list_for_each(pos, &ms_info.mi_connected) {
254 ep = list_entry(pos, struct endpt, list);
255 seq_printf(m, "%-16p\t%-16d %-16d %-16d\n",
256 ep, ep->rma_info.fence_refcount,
257 atomic_read(&ep->rma_info.tw_refcount),
258 ep->rma_info.dma_chan ? get_chan_num(ep->rma_info.dma_chan): -1);
259 }
260 spin_unlock_irqrestore(&ms_info.mi_connlock, sflags);
261 return 0;
262}
263
264static int
265scif_rma_xfer_open(struct inode *inode, struct file *file)
266{
267 return single_open(file, scif_rma_xfer_show, NULL);
268}
269
270struct file_operations scif_rma_xfer_fops = {
271 .open = scif_rma_xfer_open,
272 .read = seq_read,
273 .llseek = seq_lseek,
274 .release = single_release,
275};
276
277static int
278scif_dev_show(struct seq_file *m, void *data)
279{
280 int node;
281
282 seq_printf(m, "Total Nodes %d Self Node Id %d Maxid %d\n",
283 ms_info.mi_total, ms_info.mi_nodeid, ms_info.mi_maxid);
284
285 seq_printf(m, "%-16s\t%-16s %-16s\t%-16s\t%-8s\t%-8s\t%-8s\n",
286 "node_id", "state", "scif_ref_cnt", "scif_map_ref_cnt",
287 "wait_status", "conn count", "numa_node");
288
289 for (node = 0; node <= ms_info.mi_maxid; node++)
290 seq_printf(m, "%-16d\t%-16s\t0x%-16lx\t%-16d\t%-16lld\t%-16d\t%-16d\n",
291 scif_dev[node].sd_node, scifdev_state[scif_dev[node].sd_state],
292 atomic_long_read(&scif_dev[node].scif_ref_cnt),
293 scif_dev[node].scif_map_ref_cnt,
294 scif_dev[node].sd_wait_status,
295 scif_dev[node].num_active_conn,
296 scif_dev[node].sd_numa_node);
297
298 return 0;
299}
300
301static int
302scif_dev_open(struct inode *inode, struct file *file)
303{
304 return single_open(file, scif_dev_show, NULL);
305}
306
307struct file_operations scif_dev_fops = {
308 .open = scif_dev_open,
309 .read = seq_read,
310 .llseek = seq_lseek,
311 .release = single_release,
312};
313
314static int
315scif_debug_show(struct seq_file *m, void *data)
316{
317 seq_printf(m, "Num gtt_entries %d\n", ms_info.nr_gtt_entries);
318 /*
319 * Tracking the number of zombies for debug.
320 * Need to make sure they are not being left behind forever.
321 */
322 seq_printf(m, "Num Zombie Endpoints %d\n", ms_info.mi_nr_zombies);
323 seq_printf(m, "Watchdog timeout %d\n", ms_info.mi_watchdog_to);
324 seq_printf(m, "Watchdog enabled %d\n", ms_info.mi_watchdog_enabled);
325 seq_printf(m, "Watchdog auto reboot %d\n", ms_info.mi_watchdog_auto_reboot);
326 seq_printf(m, "Huge Pages Enabled %d Detected 2mb %lld 4k %lld\n",
327 mic_huge_page_enable, ms_info.nr_2mb_pages, ms_info.nr_4k_pages);
328#ifdef RMA_DEBUG
329 seq_printf(m, "rma_alloc_cnt %ld rma_pin_cnt %ld mmu_notif %ld rma_unaligned_cpu_cnt %ld\n",
330 atomic_long_read(&ms_info.rma_alloc_cnt),
331 atomic_long_read(&ms_info.rma_pin_cnt),
332 atomic_long_read(&ms_info.mmu_notif_cnt),
333 atomic_long_read(&ms_info.rma_unaligned_cpu_cnt));
334#endif
335 seq_printf(m, "List empty? mi_uaccept %d mi_listen %d mi_zombie %d "
336 "mi_connected %d mi_disconnected %d\n",
337 list_empty(&ms_info.mi_uaccept),
338 list_empty(&ms_info.mi_listen),
339 list_empty(&ms_info.mi_zombie),
340 list_empty(&ms_info.mi_connected),
341 list_empty(&ms_info.mi_disconnected));
342
343 return 0;
344}
345
346static int
347scif_debug_open(struct inode *inode, struct file *file)
348{
349 return single_open(file, scif_debug_show, NULL);
350}
351
352struct file_operations scif_debug_fops = {
353 .open = scif_debug_open,
354 .read = seq_read,
355 .llseek = seq_lseek,
356 .release = single_release,
357};
358
359static int
360scif_suspend_show(struct seq_file *m, void *data)
361{
362 int node;
363 uint64_t ret;
364 seq_printf(m, "Removing Nodes mask 0x7\n");
365
366 for (node = 1; node < ms_info.mi_total; node++) {
367 ret = micscif_disconnect_node(node, 0 , 1);
368 seq_printf(m, "Node %d requested disconnect. ret = %lld\n",
369 node, ret);
370 }
371
372 return 0;
373}
374
375static int
376scif_suspend_open(struct inode *inode, struct file *file)
377{
378 return single_open(file, scif_suspend_show, NULL);
379}
380
381struct file_operations scif_suspend_fops = {
382 .open = scif_suspend_open,
383 .read = seq_read,
384 .llseek = seq_lseek,
385 .release = single_release,
386};
387
388static int
389scif_cache_limit_show(struct seq_file *m, void *data)
390{
391 seq_printf(m, "reg_cache_limit = 0x%lx\n", ms_info.mi_rma_tc_limit);
392 return 0;
393}
394
395static int
396scif_cache_limit_open(struct inode *inode, struct file *file)
397{
398 return single_open(file, scif_cache_limit_show, NULL);
399}
400
401struct file_operations scif_cache_limit_fops = {
402 .open = scif_cache_limit_open,
403 .read = seq_read,
404 .llseek = seq_lseek,
405 .release = single_release,
406};
407
408#else // LINUX VERSION 3.10
409
410static int
411scif_rma_window_read(char *buf, char **start, off_t offset, int len, int *eof, void *data)
412{
413 struct endpt *ep;
414 struct list_head *pos, *item, *tmp;
415 unsigned long sflags;
416 int l = 0;
417 struct reg_range_t *window;
418
419 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
420 "SCIF Connected EP RMA Window Info\n");
421 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
422 "=================================================================\n");
423 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
424 "%-16s\t%-16s %-16s %-16s %-8s %-8s %-8s\n",
425 "Endpoint", "Type", "Offset", "NumPages", "Prot", "Ref_Count", "Unreg State");
426 spin_lock_irqsave(&ms_info.mi_connlock, sflags);
427 list_for_each(pos, &ms_info.mi_connected) {
428 ep = list_entry(pos, struct endpt, list);
429 if (mutex_trylock(&ep->rma_info.rma_lock)) {
430 list_for_each_safe(item, tmp, &ep->rma_info.reg_list) {
431 window = list_entry(item, struct reg_range_t, list_member);
432 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
433 "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
434 ep, window_type[window->type], window->offset,
435 window->nr_pages, window->prot, window->ref_count,
436 window->unreg_state);
437 }
438 list_for_each_safe(item, tmp, &ep->rma_info.remote_reg_list) {
439 window = list_entry(item, struct reg_range_t, list_member);
440 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
441 "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
442 ep, window_type[window->type], window->offset,
443 window->nr_pages, window->prot, window->ref_count,
444 window->unreg_state);
445 }
446 mutex_unlock(&ep->rma_info.rma_lock);
447 } else
448 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
449 "Try Again, some other thread has the RMA lock for ep %p\n",
450 ep);
451 }
452 spin_unlock_irqrestore(&ms_info.mi_connlock, sflags);
453
454 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
455 "=================================================================\n");
456 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
457 "SCIF Zombie EP RMA Window Info\n");
458 spin_lock_irqsave(&ms_info.mi_eplock, sflags);
459 list_for_each(pos, &ms_info.mi_zombie) {
460 ep = list_entry(pos, struct endpt, list);
461 if (mutex_trylock(&ep->rma_info.rma_lock)) {
462 list_for_each_safe(item, tmp, &ep->rma_info.reg_list) {
463 window = list_entry(item, struct reg_range_t, list_member);
464 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
465 "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
466 ep, window_type[window->type], window->offset,
467 window->nr_pages, window->prot, window->ref_count,
468 window->unreg_state);
469 }
470 list_for_each_safe(item, tmp, &ep->rma_info.remote_reg_list) {
471 window = list_entry(item, struct reg_range_t, list_member);
472 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
473 "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
474 ep, window_type[window->type], window->offset,
475 window->nr_pages, window->prot, window->ref_count,
476 window->unreg_state);
477 }
478 mutex_unlock(&ep->rma_info.rma_lock);
479 } else
480 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
481 "Try Again, some other thread has the RMA lock for ep %p\n",
482 ep);
483 }
484 spin_unlock_irqrestore(&ms_info.mi_eplock, sflags);
485 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
486 "=================================================================\n");
487 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
488 "%-16s\t%-16s %-16s %-16s %-8s %-8s %-8s\n",
489 "Endpoint", "Type", "Offset", "NumPages", "Prot", "Ref_Count", "Unreg State");
490 spin_lock(&ms_info.mi_rmalock);
491 list_for_each_safe(item, tmp, &ms_info.mi_rma) {
492 window = list_entry(item,
493 struct reg_range_t, list_member);
494 ep = (struct endpt *)window->ep;
495 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
496 "%-16p\t%-16s 0x%-16llx %-16lld %-8d %-8d %-8d\n",
497 ep, window_type[window->type], window->offset,
498 window->nr_pages, window->prot, window->ref_count,
499 window->unreg_state);
500 }
501 spin_unlock(&ms_info.mi_rmalock);
502
503 *eof = 1;
504 return l;
505}
506
507static int
508scif_rma_xfer_read(char *buf, char **start, off_t offset, int len, int *eof, void *data)
509{
510 struct endpt *ep;
511 struct list_head *pos;
512 unsigned long sflags;
513 int l = 0;
514
515 l += snprintf(buf + l, len - l > 0 ? len - l : 0 , "SCIF RMA Debug\n");
516 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
517 "=================================================================\n");
518 l += snprintf(buf + l, len - l > 0 ? len - l : 0 , "%-16s\t %-16s %-16s %-16s\n",
519 "Endpoint", "Fence Ref Count", "Temp Window Ref Count", "DMA CHANNEL");
520 spin_lock_irqsave(&ms_info.mi_connlock, sflags);
521 list_for_each(pos, &ms_info.mi_connected) {
522 ep = list_entry(pos, struct endpt, list);
523 l += snprintf(buf + l, len - l > 0 ? len - l : 0 , "%-16p\t%-16d %-16d %-16d\n",
524 ep, ep->rma_info.fence_refcount,
525 atomic_read(&ep->rma_info.tw_refcount),
526 ep->rma_info.dma_chan ? get_chan_num(ep->rma_info.dma_chan): -1);
527 }
528 spin_unlock_irqrestore(&ms_info.mi_connlock, sflags);
529
530 *eof = 1;
531 return l;
532}
533
534/* Place Holder for generic SCIF debug information */
535static int
536scif_debug_read(char *buf, char **start, off_t offset, int len, int *eof, void *data)
537{
538 int l = 0;
539
540 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
541 "Num gtt_entries %d\n", ms_info.nr_gtt_entries);
542 /*
543 * Tracking the number of zombies for debug.
544 * Need to make sure they are not being left behind forever.
545 */
546 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
547 "Num Zombie Endpoints %d\n", ms_info.mi_nr_zombies);
548
549 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
550 "Watchdog timeout %d\n", ms_info.mi_watchdog_to);
551
552 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
553 "Watchdog enabled %d\n", ms_info.mi_watchdog_enabled);
554
555 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
556 "Watchdog auto reboot %d\n", ms_info.mi_watchdog_auto_reboot);
557
558 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
559 "Huge Pages Enabled %d Detected 2mb %lld 4k %lld\n",
560 mic_huge_page_enable, ms_info.nr_2mb_pages, ms_info.nr_4k_pages);
561#ifdef RMA_DEBUG
562 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
563 "mm ref cnt %ld rma_alloc_cnt %ld rma_pin_cnt %ld mmu_notif %ld rma_unaligned_cpu_cnt %ld\n",
564 atomic_long_read(&ms_info.rma_mm_cnt),
565 atomic_long_read(&ms_info.rma_alloc_cnt),
566 atomic_long_read(&ms_info.rma_pin_cnt),
567 atomic_long_read(&ms_info.mmu_notif_cnt),
568 atomic_long_read(&ms_info.rma_unaligned_cpu_cnt));
569#endif
570 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
571 "List empty? mi_uaccept %d mi_listen %d mi_zombie %d "
572 "mi_connected %d mi_disconnected %d\n",
573 list_empty(&ms_info.mi_uaccept),
574 list_empty(&ms_info.mi_listen),
575 list_empty(&ms_info.mi_zombie),
576 list_empty(&ms_info.mi_connected),
577 list_empty(&ms_info.mi_disconnected));
578
579 *eof = 1;
580 return l;
581}
582
583static int
584scif_dev_info(char *buf, char **start, off_t offset, int len, int *eof, void *data)
585{
586 int l = 0;
587 int node;
588
589#ifdef _MIC_SCIF_
590 micscif_get_node_info();
591
592 mutex_lock(&ms_info.mi_conflock);
593#endif
594 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
595 "Total Nodes %d Self Node Id %d Maxid %d\n",
596 ms_info.mi_total, ms_info.mi_nodeid, ms_info.mi_maxid);
597
598 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
599 "%-16s\t%-16s %-16s\t%-16s\t%-8s\t%-8s\t%-8s\n",
600 "node_id", "state", "scif_ref_cnt", "scif_map_ref_cnt",
601 "wait_status", "conn count", "numa_node");
602
603 for (node = 0; node <= ms_info.mi_maxid; node++)
604 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
605 "%-16d\t%-16s\t0x%-16lx\t%-16d\t%-16lld\t%-16d\t%-16d\n",
606 scif_dev[node].sd_node, scifdev_state[scif_dev[node].sd_state],
607 atomic_long_read(&scif_dev[node].scif_ref_cnt),
608 scif_dev[node].scif_map_ref_cnt,
609 scif_dev[node].sd_wait_status,
610 scif_dev[node].num_active_conn,
611 scif_dev[node].sd_numa_node);
612#ifdef _MIC_SCIF_
613 mutex_unlock(&ms_info.mi_conflock);
614#endif
615
616 *eof = 1;
617 return l;
618}
619
620static int
621scif_suspend(char *buf, char **start, off_t offset, int len, int *eof, void *data)
622{
623 int l = 0;
624
625#ifdef _MIC_SCIF_
626 micscif_suspend_handler(NULL, 0, NULL);
627#else
628 {
629 int node;
630 uint64_t ret;
631 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
632 "Removing Nodes mask 0x7\n");
633 for (node = 1; node < ms_info.mi_total; node++) {
634 ret = micscif_disconnect_node(node, 0 , 1);
635 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
636 "Node %d requested disconnect. ret = %lld\n",
637 node, ret);
638 }
639 }
640#endif
641
642 *eof = 1;
643 return l;
644}
645
646#ifdef _MIC_SCIF_
647static int
648scif_crash(char *buf, char **start, off_t offset, int len, int *eof, void *data)
649{
650 int l = 0;
651 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
652 "%s %d Crash the Card to test Lost Nodes\n", __func__, __LINE__);
653 panic("Test Lost Node! Crash the card intentionally\n");
654 *eof = 1;
655 return l;
656}
657
658static int
659scif_bugon(char *buf, char **start, off_t offset, int len, int *eof, void *data)
660{
661 int l = 0;
662 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
663 "%s %d Bug on the Card to test Lost Nodes\n", __func__, __LINE__);
664 BUG_ON(1);
665 *eof = 1;
666 return l;
667}
668#endif
669
670static int
671scif_fail_suspend(char *buf, char **start, off_t offset, int len, int *eof, void *data)
672{
673 int l = 0;
674
675#ifdef _MIC_SCIF_
676 micscif_fail_suspend_handler(NULL, 0, NULL);
677 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
678 "Failing Suspend\n");
679#endif
680
681 *eof = 1;
682 return l;
683}
684
685static int
686scif_resume(char *buf, char **start, off_t offset, int len, int *eof, void *data)
687{
688 int l = 0;
689
690#ifdef _MIC_SCIF_
691 micscif_resume_handler(NULL, 0, NULL);
692 l += snprintf(buf + l, len - l > 0 ? len - l : 0,
693 "Resuming/Waking up node\n");
694#endif
695
696 *eof = 1;
697 return l;
698}
699
700static int
701scif_get_reg_cache_limit(char *buf, char **start, off_t offset, int len, int *eof, void *data)
702{
703 int l = 0;
704
705 l += snprintf(buf + l, len - l > 0 ? len - l : 0 ,
706 "reg_cache_limit = 0x%lx\n", ms_info.mi_rma_tc_limit);
707 *eof = 1;
708 return l;
709}
710
711static int
712scif_set_reg_cache_limit(struct file *file, const char __user *buffer,
713 unsigned long len, void *unused)
714{
715 unsigned long data = 0;
716 char *p;
717 if (!(p = kzalloc(len, GFP_KERNEL)))
718 return -ENOMEM;
719 if (copy_from_user(p, buffer, len))
720 return -EFAULT;
721 data = simple_strtoul(p, NULL, 0);
722 ms_info.mi_rma_tc_limit = data;
723 return len;
724}
725#endif
726
727#ifdef _MIC_SCIF_
728static int smpt_seq_show(struct seq_file *s, void *pos)
729{
730 volatile uint8_t *mm_sbox = scif_dev[SCIF_HOST_NODE].mm_sbox;
731 uint32_t smpt_reg_offset = SBOX_SMPT00;
732 uint32_t smpt_reg_val;
733 int i;
734
735 seq_printf(s,
736 "=================================================================\n");
737 seq_printf(s,"%-11s| %-15s %-14s %-5s \n",
738 "SMPT entry", "SMPT reg value", "DMA addr", "SNOOP");
739 seq_printf(s,
740 "=================================================================\n");
741
742 for (i = 0; i < NUM_SMPT_ENTRIES_IN_USE; i++) {
743 smpt_reg_val = readl(mm_sbox + smpt_reg_offset);
744 seq_printf(s,"%-11d| %-#15x %-#14llx %-5s \n",
745 i, smpt_reg_val, ((uint64_t)smpt_reg_val >> 2ULL) << MIC_SYSTEM_PAGE_SHIFT,
746 (smpt_reg_val & 0x1) ? "OFF" : "ON");
747 smpt_reg_offset += 4;
748 }
749
750 seq_printf(s,
751 "=================================================================\n");
752 return 0;
753}
754
755#else
756static int smpt_seq_show(struct seq_file *s, void *pos)
757{
758 uint64_t bid = (uint64_t)s->private;
759 mic_ctx_t *mic_ctx;
760 int i;
761 unsigned long flags;
762
763 mic_ctx = get_per_dev_ctx(bid);
764 seq_printf(s,
765 "=================================================================\n");
766 seq_printf(s,"Board %-2d |%-10s| %-14s %-10s \n",
767 (int)bid + 1, "SMPT entry", "DMA addr", "Reference Count");
768 seq_printf(s,
769 "=================================================================\n");
770
771 if (mic_ctx && mic_ctx->mic_smpt) {
772 spin_lock_irqsave(&mic_ctx->smpt_lock, flags);
773 for (i = 0; i < NUM_SMPT_ENTRIES_IN_USE; i++) {
774 seq_printf(s,"%9s|%-10d| %-#14llx %-10lld \n",
775 " ", i, mic_ctx->mic_smpt[i].dma_addr, mic_ctx->mic_smpt[i].ref_count);
776 }
777 spin_unlock_irqrestore(&mic_ctx->smpt_lock, flags);
778 }
779
780 seq_printf(s,
781 "================================================================X\n");
782 return 0;
783}
784#endif
785
786static int smpt_debug_open(struct inode *inode, struct file *file)
787{
788 return single_open(file, smpt_seq_show, inode->i_private);
789}
790
791static int smpt_debug_release(struct inode *inode, struct file *file)
792{
793 return single_release(inode, file);
794}
795
796static struct file_operations smpt_file_ops = {
797 .owner = THIS_MODULE,
798 .open = smpt_debug_open,
799 .read = seq_read,
800 .llseek = seq_lseek,
801 .release = smpt_debug_release
802};
803
804#ifndef _MIC_SCIF_
805static int log_buf_seq_show(struct seq_file *s, void *pos)
806{
807 uint64_t bid = (uint64_t)s->private;
808 mic_ctx_t *mic_ctx;
809 void *log_buf_len_va, *log_buf_va;
810 struct micscif_dev *dev;
811
812 mic_ctx = get_per_dev_ctx(bid);
813 if (!mic_ctx || !mic_ctx->log_buf_addr || !mic_ctx->log_buf_len)
814 goto done;
815
816 if (mic_ctx->bi_family == FAMILY_ABR) {
817 seq_printf(s, "log buffer display not supported for KNF\n");
818 goto done;
819 }
820
821 dev = &scif_dev[mic_get_scifnode_id(mic_ctx)];
822 log_buf_len_va = virt_to_phys(mic_ctx->log_buf_len) + mic_ctx->aper.va;
823 log_buf_va = virt_to_phys(mic_ctx->log_buf_addr) + mic_ctx->aper.va;
824
825 mutex_lock(&mic_ctx->state_lock);
826 switch (mic_ctx->state) {
827 case MIC_BOOT:
828 case MIC_BOOTFAIL:
829 case MIC_ONLINE:
830 case MIC_SHUTDOWN:
831 case MIC_LOST:
832 micscif_inc_node_refcnt(dev, 1);
833 seq_write(s, log_buf_va, *(int*)log_buf_len_va);
834 micscif_dec_node_refcnt(dev, 1);
835 break;
836 case MIC_NORESPONSE:
837 case MIC_READY:
838 /* Cannot access GDDR while reset is ongoing */
839 case MIC_RESET:
840 case MIC_RESETFAIL:
841 case MIC_INVALID:
842 default:
843 break;
844 }
845 mutex_unlock(&mic_ctx->state_lock);
846done:
847 return 0;
848}
849
850static int log_buf_open(struct inode *inode, struct file *file)
851{
852 return single_open(file, log_buf_seq_show, inode->i_private);
853}
854
855static int log_buf_release(struct inode *inode, struct file *file)
856{
857 return single_release(inode, file);
858}
859
860static struct file_operations log_buf_ops = {
861 .owner = THIS_MODULE,
862 .open = log_buf_open,
863 .read = seq_read,
864 .llseek = seq_lseek,
865 .release = log_buf_release
866};
867#endif
868
869#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
870void
871scif_proc_init(void)
872{
873 if ((scif_proc = proc_mkdir("scif", NULL)) != NULL) {
874 proc_create_data("ep", 0444, scif_proc, &scif_ep_fops, NULL);
875 proc_create_data("rma_window", 0444, scif_proc, &scif_rma_window_fops, NULL);
876 proc_create_data("rma_xfer", 0444, scif_proc, &scif_rma_xfer_fops, NULL);
877 proc_create_data("scif_dev", 0444, scif_proc, &scif_dev_fops, NULL);
878 proc_create_data("debug", 0444, scif_proc, &scif_debug_fops, NULL);
879 proc_create_data("suspend", 0444, scif_proc, &scif_suspend_fops, NULL);
880 proc_create("reg_cache_limit", S_IFREG | S_IRUGO | S_IWUGO, scif_proc,
881 &scif_cache_limit_fops);
882 }
883}
884#else
885void
886scif_proc_init(void)
887{
888 struct proc_dir_entry *reg_cache_limit_entry;
889 struct proc_dir_entry *ep_entry;
890
891 if ((scif_proc = create_proc_entry("scif", S_IFDIR | S_IRUGO, NULL)) != NULL) {
892 create_proc_read_entry("rma_window", 0444, scif_proc, scif_rma_window_read, NULL);
893 create_proc_read_entry("rma_xfer", 0444, scif_proc, scif_rma_xfer_read, NULL);
894 create_proc_read_entry("scif_dev", 0444, scif_proc, scif_dev_info, NULL);
895 create_proc_read_entry("debug", 0444, scif_proc, scif_debug_read, NULL);
896 create_proc_read_entry("suspend", 0444, scif_proc, scif_suspend, NULL);
897 create_proc_read_entry("fail_suspend", 0444, scif_proc, scif_fail_suspend, NULL);
898 create_proc_read_entry("resume", 0444, scif_proc, scif_resume, NULL);
899#ifdef _MIC_SCIF_
900 create_proc_read_entry("crash", 0444, scif_proc, scif_crash, NULL);
901 create_proc_read_entry("bugon", 0444, scif_proc, scif_bugon, NULL);
902#endif
903 if ((reg_cache_limit_entry = create_proc_entry("reg_cache_limit", S_IFREG | S_IRUGO | S_IWUGO, scif_proc))) {
904 reg_cache_limit_entry->write_proc = scif_set_reg_cache_limit;
905 reg_cache_limit_entry->read_proc = scif_get_reg_cache_limit;
906 reg_cache_limit_entry->data = NULL;
907 }
908 if ((ep_entry = create_proc_entry("ep", S_IFREG | S_IRUGO | S_IWUGO, scif_proc))) {
909 ep_entry->proc_fops = &scif_ep_fops;
910 }
911
912
913 }
914}
915#endif // LINUX VERSION
916
917#ifdef _MIC_SCIF_
918void
919mic_debug_init(void)
920{
921 if ((mic_debug = debugfs_create_dir("mic_debug", NULL))) {
922 debugfs_create_file("smpt", 0444, mic_debug, NULL, &smpt_file_ops);
923 debugfs_create_u8("enable_msg_logging", 0666, mic_debug, &(ms_info.en_msg_log));
924 }
925}
926#else
927void
928mic_debug_init(mic_ctx_t *mic_ctx)
929{
930 char name[DEBUG_LEN];
931 uint64_t id = mic_ctx->bi_id;
932 struct dentry *child;
933
934 if (!mic_debug)
935 mic_debug = debugfs_create_dir("mic_debug", NULL);
936
937 if (mic_debug) {
938 snprintf(name, DEBUG_LEN, "mic%d", (int)id);
939 if ((child = debugfs_create_dir(name, mic_debug))) {
940 debugfs_create_file("smpt", 0444, child, (void*)id, &smpt_file_ops);
941 debugfs_create_file("log_buf", 0444, child, (void*)id, &log_buf_ops);
942 }
943 debugfs_create_u8("enable_msg_logging", 0666, mic_debug, &(ms_info.en_msg_log));
944 }
945}
946#endif
947
948void
949mic_debug_uninit(void)
950{
951 debugfs_remove_recursive(mic_debug);
952}
953
954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
955void
956scif_proc_cleanup(void)
957{
958 if (scif_proc)
959 remove_proc_subtree("scif", NULL);
960}
961#else
962void
963scif_proc_cleanup(void)
964{
965 if (scif_proc) {
966 remove_proc_entry("reg_cache_limit", scif_proc);
967 remove_proc_entry("ep", scif_proc);
968 remove_proc_entry("rma_window", scif_proc);
969 remove_proc_entry("rma_xfer", scif_proc);
970 remove_proc_entry("scif_dev", scif_proc);
971 remove_proc_entry("debug", scif_proc);
972 remove_proc_entry("suspend", scif_proc);
973 remove_proc_entry("fail_suspend", scif_proc);
974 remove_proc_entry("resume", scif_proc);
975#ifdef _MIC_SCIF_
976 remove_proc_entry("crash", scif_proc);
977 remove_proc_entry("bugon", scif_proc);
978#endif
979 remove_proc_entry("scif", NULL);
980 scif_proc = NULL;
981 }
982}
983#endif
984
985#ifdef _MIC_SCIF_
986extern int micscif_max_msg_id;
987
988/*
989 * Test entry point for error injection
990 */
991int
992micscif_error_inject(int scenario)
993{
994 switch (scenario) {
995 case 1:
996 micscif_max_msg_id = 0;
997 break;
998 default:
999 pr_debug("Illegal error injection scenario %d\n", scenario);
1000 return -EINVAL;
1001 }
1002 return 0;
1003}
1004EXPORT_SYMBOL(micscif_error_inject);
1005#endif // _MIC_SCIF_