1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
6 * This file is part of Portals
7 * http://sourceforge.net/projects/sandiaportals/
9 * Portals is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Portals is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Portals; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #define DEBUG_SUBSYSTEM S_LNET
25 #include <libcfs/libcfs.h>
26 #include <lnet/lib-lnet.h>
28 #if defined(__KERNEL__) && defined(LNET_ROUTER)
30 #if defined(__linux__)
31 #include <linux/seq_file.h>
34 /* this is really lnet_proc.c */
36 #define LNET_PROC_STATS "sys/lnet/stats"
37 #define LNET_PROC_ROUTES "sys/lnet/routes"
38 #define LNET_PROC_ROUTERS "sys/lnet/routers"
39 #define LNET_PROC_PEERS "sys/lnet/peers"
40 #define LNET_PROC_BUFFERS "sys/lnet/buffers"
41 #define LNET_PROC_NIS "sys/lnet/nis"
44 lnet_router_proc_stats_read (char *page, char **start, off_t off,
45 int count, int *eof, void *data)
47 lnet_counters_t *ctrs;
55 LIBCFS_ALLOC(ctrs, sizeof(*ctrs));
60 *ctrs = the_lnet.ln_counters;
64 "%u %u %u %u %u %u %u "LPU64" "LPU64" "LPU64" "LPU64"\n",
65 ctrs->msgs_alloc, ctrs->msgs_max,
67 ctrs->send_count, ctrs->recv_count,
68 ctrs->route_count, ctrs->drop_count,
69 ctrs->send_length, ctrs->recv_length,
70 ctrs->route_length, ctrs->drop_length);
72 LIBCFS_FREE(ctrs, sizeof(*ctrs));
77 lnet_router_proc_stats_write(struct file *file, const char *ubuffer,
78 unsigned long count, void *data)
81 memset(&the_lnet.ln_counters, 0, sizeof(the_lnet.ln_counters));
89 lnet_remotenet_t *lrsi_net;
90 lnet_route_t *lrsi_route;
92 } lnet_route_seq_iterator_t;
95 lnet_route_seq_seek (lnet_route_seq_iterator_t *lrsi, loff_t off)
103 lrsi->lrsi_net = NULL;
104 lrsi->lrsi_route = NULL;
111 if (lrsi->lrsi_net != NULL &&
112 lrsi->lrsi_version != the_lnet.ln_remote_nets_version) {
113 /* tables have changed */
118 if (lrsi->lrsi_net == NULL || lrsi->lrsi_off > off) {
119 /* search from start */
120 n = the_lnet.ln_remote_nets.next;
124 /* continue search */
125 n = &lrsi->lrsi_net->lrn_list;
126 r = &lrsi->lrsi_route->lr_list;
127 here = lrsi->lrsi_off;
130 lrsi->lrsi_version = the_lnet.ln_remote_nets_version;
131 lrsi->lrsi_off = off;
133 while (n != &the_lnet.ln_remote_nets) {
134 lnet_remotenet_t *rnet =
135 list_entry(n, lnet_remotenet_t, lrn_list);
138 r = rnet->lrn_routes.next;
140 while (r != &rnet->lrn_routes) {
142 list_entry(r, lnet_route_t,
146 lrsi->lrsi_net = rnet;
147 lrsi->lrsi_route = re;
160 lrsi->lrsi_net = NULL;
161 lrsi->lrsi_route = NULL;
169 lnet_route_seq_start (struct seq_file *s, loff_t *pos)
171 lnet_route_seq_iterator_t *lrsi;
174 LIBCFS_ALLOC(lrsi, sizeof(*lrsi));
178 lrsi->lrsi_net = NULL;
179 rc = lnet_route_seq_seek(lrsi, *pos);
183 LIBCFS_FREE(lrsi, sizeof(*lrsi));
188 lnet_route_seq_stop (struct seq_file *s, void *iter)
190 lnet_route_seq_iterator_t *lrsi = iter;
193 LIBCFS_FREE(lrsi, sizeof(*lrsi));
197 lnet_route_seq_next (struct seq_file *s, void *iter, loff_t *pos)
199 lnet_route_seq_iterator_t *lrsi = iter;
201 loff_t next = *pos + 1;
203 rc = lnet_route_seq_seek(lrsi, next);
205 LIBCFS_FREE(lrsi, sizeof(*lrsi));
214 lnet_route_seq_show (struct seq_file *s, void *iter)
216 lnet_route_seq_iterator_t *lrsi = iter;
222 if (lrsi->lrsi_off == 0) {
223 seq_printf(s, "Routing %s\n",
224 the_lnet.ln_routing ? "enabled" : "disabled");
225 seq_printf(s, "%-8s %4s %7s %s\n",
226 "net", "hops", "state", "router");
230 LASSERT (lrsi->lrsi_net != NULL);
231 LASSERT (lrsi->lrsi_route != NULL);
235 if (lrsi->lrsi_version != the_lnet.ln_remote_nets_version) {
240 net = lrsi->lrsi_net->lrn_net;
241 hops = lrsi->lrsi_net->lrn_hops;
242 nid = lrsi->lrsi_route->lr_gateway->lp_nid;
243 alive = lrsi->lrsi_route->lr_gateway->lp_alive;
247 seq_printf(s, "%-8s %4u %7s %s\n", libcfs_net2str(net), hops,
248 alive ? "up" : "down", libcfs_nid2str(nid));
252 static struct seq_operations lnet_routes_sops = {
253 /* start */ lnet_route_seq_start,
254 /* stop */ lnet_route_seq_stop,
255 /* next */ lnet_route_seq_next,
256 /* show */ lnet_route_seq_show,
260 lnet_route_seq_open(struct inode *inode, struct file *file)
262 struct proc_dir_entry *dp = PDE(inode);
266 rc = seq_open(file, &lnet_routes_sops);
268 sf = file->private_data;
269 sf->private = dp->data;
275 static struct file_operations lnet_routes_fops;
278 lnet_init_routes_fops(void)
280 lnet_routes_fops.owner = THIS_MODULE;
281 lnet_routes_fops.llseek = seq_lseek;
282 lnet_routes_fops.read = seq_read;
283 lnet_routes_fops.open = lnet_route_seq_open;
284 lnet_routes_fops.release = seq_release;
288 __u64 lrtrsi_version;
289 lnet_peer_t *lrtrsi_router;
291 } lnet_router_seq_iterator_t;
294 lnet_router_seq_seek (lnet_router_seq_iterator_t *lrtrsi, loff_t off)
302 lrtrsi->lrtrsi_router = NULL;
303 lrtrsi->lrtrsi_off = 0;
309 lp = lrtrsi->lrtrsi_router;
312 lrtrsi->lrtrsi_version != the_lnet.ln_routers_version) {
313 /* tables have changed */
318 if (lp == NULL || lrtrsi->lrtrsi_off > off) {
319 /* search from start */
320 r = the_lnet.ln_routers.next;
323 /* continue search */
324 r = &lp->lp_rtr_list;
325 here = lrtrsi->lrtrsi_off;
328 lrtrsi->lrtrsi_version = the_lnet.ln_routers_version;
329 lrtrsi->lrtrsi_off = off;
331 while (r != &the_lnet.ln_routers) {
332 lnet_peer_t *rtr = list_entry(r,
337 lrtrsi->lrtrsi_router = rtr;
346 lrtrsi->lrtrsi_router = NULL;
354 lnet_router_seq_start (struct seq_file *s, loff_t *pos)
356 lnet_router_seq_iterator_t *lrtrsi;
359 LIBCFS_ALLOC(lrtrsi, sizeof(*lrtrsi));
363 lrtrsi->lrtrsi_router = NULL;
364 rc = lnet_router_seq_seek(lrtrsi, *pos);
368 LIBCFS_FREE(lrtrsi, sizeof(*lrtrsi));
373 lnet_router_seq_stop (struct seq_file *s, void *iter)
375 lnet_router_seq_iterator_t *lrtrsi = iter;
378 LIBCFS_FREE(lrtrsi, sizeof(*lrtrsi));
382 lnet_router_seq_next (struct seq_file *s, void *iter, loff_t *pos)
384 lnet_router_seq_iterator_t *lrtrsi = iter;
386 loff_t next = *pos + 1;
388 rc = lnet_router_seq_seek(lrtrsi, next);
390 LIBCFS_FREE(lrtrsi, sizeof(*lrtrsi));
399 lnet_router_seq_show (struct seq_file *s, void *iter)
401 lnet_router_seq_iterator_t *lrtrsi = iter;
410 if (lrtrsi->lrtrsi_off == 0) {
411 seq_printf(s, "%-4s %7s %9s %6s %12s %s\n",
412 "ref", "rtr_ref", "alive_cnt", "state", "last_ping", "router");
416 lp = lrtrsi->lrtrsi_router;
417 LASSERT (lp != NULL);
421 if (lrtrsi->lrtrsi_version != the_lnet.ln_routers_version) {
427 alive = lp->lp_alive;
428 alive_cnt = lp->lp_alive_count;
429 nrefs = lp->lp_refcount;
430 nrtrrefs = lp->lp_rtr_refcount;
431 last_ping = lp->lp_ping_timestamp;
436 "%-4d %7d %9d %6s %12lu %s\n", nrefs, nrtrrefs,
437 alive_cnt, alive ? "up" : "down",
438 last_ping, libcfs_nid2str(nid));
442 static struct seq_operations lnet_routers_sops = {
443 /* start */ lnet_router_seq_start,
444 /* stop */ lnet_router_seq_stop,
445 /* next */ lnet_router_seq_next,
446 /* show */ lnet_router_seq_show,
450 lnet_router_seq_open(struct inode *inode, struct file *file)
452 struct proc_dir_entry *dp = PDE(inode);
456 rc = seq_open(file, &lnet_routers_sops);
458 sf = file->private_data;
459 sf->private = dp->data;
465 static struct file_operations lnet_routers_fops;
468 lnet_init_routers_fops(void)
470 lnet_routers_fops.owner = THIS_MODULE;
471 lnet_routers_fops.llseek = seq_lseek;
472 lnet_routers_fops.read = seq_read;
473 lnet_routers_fops.open = lnet_router_seq_open;
474 lnet_routers_fops.release = seq_release;
478 unsigned long long lpsi_version;
480 lnet_peer_t *lpsi_peer;
482 } lnet_peer_seq_iterator_t;
485 lnet_peer_seq_seek (lnet_peer_seq_iterator_t *lpsi, loff_t off)
494 lpsi->lpsi_peer = NULL;
501 if (lpsi->lpsi_peer != NULL &&
502 lpsi->lpsi_version != the_lnet.ln_peertable_version) {
503 /* tables have changed */
508 if (lpsi->lpsi_peer == NULL ||
509 lpsi->lpsi_off > off) {
510 /* search from start */
515 /* continue search */
516 idx = lpsi->lpsi_idx;
517 p = &lpsi->lpsi_peer->lp_hashlist;
518 here = lpsi->lpsi_off;
521 lpsi->lpsi_version = the_lnet.ln_peertable_version;
522 lpsi->lpsi_off = off;
524 while (idx < LNET_PEER_HASHSIZE) {
526 p = the_lnet.ln_peer_hash[idx].next;
528 while (p != &the_lnet.ln_peer_hash[idx]) {
529 lnet_peer_t *lp = list_entry(p, lnet_peer_t,
533 lpsi->lpsi_idx = idx;
534 lpsi->lpsi_peer = lp;
540 p = lp->lp_hashlist.next;
548 lpsi->lpsi_peer = NULL;
556 lnet_peer_seq_start (struct seq_file *s, loff_t *pos)
558 lnet_peer_seq_iterator_t *lpsi;
561 LIBCFS_ALLOC(lpsi, sizeof(*lpsi));
566 lpsi->lpsi_peer = NULL;
567 rc = lnet_peer_seq_seek(lpsi, *pos);
571 LIBCFS_FREE(lpsi, sizeof(*lpsi));
576 lnet_peer_seq_stop (struct seq_file *s, void *iter)
578 lnet_peer_seq_iterator_t *lpsi = iter;
581 LIBCFS_FREE(lpsi, sizeof(*lpsi));
585 lnet_peer_seq_next (struct seq_file *s, void *iter, loff_t *pos)
587 lnet_peer_seq_iterator_t *lpsi = iter;
589 loff_t next = *pos + 1;
591 rc = lnet_peer_seq_seek(lpsi, next);
593 LIBCFS_FREE(lpsi, sizeof(*lpsi));
602 lnet_peer_seq_show (struct seq_file *s, void *iter)
604 lnet_peer_seq_iterator_t *lpsi = iter;
617 if (lpsi->lpsi_off == 0) {
618 seq_printf(s, "%-24s %4s %5s %5s %5s %5s %5s %5s %s\n",
619 "nid", "refs", "state", "max",
620 "rtr", "min", "tx", "min", "queue");
624 LASSERT (lpsi->lpsi_peer != NULL);
628 if (lpsi->lpsi_version != the_lnet.ln_peertable_version) {
633 lp = lpsi->lpsi_peer;
636 maxcr = lp->lp_ni->ni_peertxcredits;
637 txcr = lp->lp_txcredits;
638 mintxcr = lp->lp_mintxcredits;
639 rtrcr = lp->lp_rtrcredits;
640 minrtrcr = lp->lp_minrtrcredits;
641 rtr = lnet_isrouter(lp);
642 alive = lp->lp_alive;
643 txqnob = lp->lp_txqnob;
644 nrefs = lp->lp_refcount;
648 seq_printf(s, "%-24s %4d %5s %5d %5d %5d %5d %5d %d\n",
649 libcfs_nid2str(nid), nrefs,
650 !rtr ? "~rtr" : (alive ? "up" : "down"),
651 maxcr, rtrcr, minrtrcr, txcr, mintxcr, txqnob);
655 static struct seq_operations lnet_peer_sops = {
656 /* start */ lnet_peer_seq_start,
657 /* stop */ lnet_peer_seq_stop,
658 /* next */ lnet_peer_seq_next,
659 /* show */ lnet_peer_seq_show,
663 lnet_peer_seq_open(struct inode *inode, struct file *file)
665 struct proc_dir_entry *dp = PDE(inode);
669 rc = seq_open(file, &lnet_peer_sops);
671 sf = file->private_data;
672 sf->private = dp->data;
678 static struct file_operations lnet_peer_fops;
681 lnet_init_peer_fops(void)
683 lnet_peer_fops.owner = THIS_MODULE;
684 lnet_peer_fops.llseek = seq_lseek;
685 lnet_peer_fops.read = seq_read;
686 lnet_peer_fops.open = lnet_peer_seq_open;
687 lnet_peer_fops.release = seq_release;
693 } lnet_buffer_seq_iterator_t;
696 lnet_buffer_seq_seek (lnet_buffer_seq_iterator_t *lbsi, loff_t off)
710 if (lbsi->lbsi_idx < 0 ||
711 lbsi->lbsi_off > off) {
712 /* search from start */
716 /* continue search */
717 idx = lbsi->lbsi_idx;
718 here = lbsi->lbsi_off;
721 lbsi->lbsi_off = off;
723 while (idx < LNET_NRBPOOLS) {
725 lbsi->lbsi_idx = idx;
741 lnet_buffer_seq_start (struct seq_file *s, loff_t *pos)
743 lnet_buffer_seq_iterator_t *lbsi;
746 LIBCFS_ALLOC(lbsi, sizeof(*lbsi));
751 rc = lnet_buffer_seq_seek(lbsi, *pos);
755 LIBCFS_FREE(lbsi, sizeof(*lbsi));
760 lnet_buffer_seq_stop (struct seq_file *s, void *iter)
762 lnet_buffer_seq_iterator_t *lbsi = iter;
765 LIBCFS_FREE(lbsi, sizeof(*lbsi));
769 lnet_buffer_seq_next (struct seq_file *s, void *iter, loff_t *pos)
771 lnet_buffer_seq_iterator_t *lbsi = iter;
773 loff_t next = *pos + 1;
775 rc = lnet_buffer_seq_seek(lbsi, next);
777 LIBCFS_FREE(lbsi, sizeof(*lbsi));
786 lnet_buffer_seq_show (struct seq_file *s, void *iter)
788 lnet_buffer_seq_iterator_t *lbsi = iter;
789 lnet_rtrbufpool_t *rbp;
795 if (lbsi->lbsi_off == 0) {
796 seq_printf(s, "%5s %5s %7s %7s\n",
797 "pages", "count", "credits", "min");
801 LASSERT (lbsi->lbsi_idx >= 0 && lbsi->lbsi_idx < LNET_NRBPOOLS);
805 rbp = &the_lnet.ln_rtrpools[lbsi->lbsi_idx];
807 npages = rbp->rbp_npages;
808 nbuf = rbp->rbp_nbuffers;
809 cr = rbp->rbp_credits;
810 mincr = rbp->rbp_mincredits;
814 seq_printf(s, "%5d %5d %7d %7d\n",
815 npages, nbuf, cr, mincr);
819 static struct seq_operations lnet_buffer_sops = {
820 /* start */ lnet_buffer_seq_start,
821 /* stop */ lnet_buffer_seq_stop,
822 /* next */ lnet_buffer_seq_next,
823 /* show */ lnet_buffer_seq_show,
827 lnet_buffer_seq_open(struct inode *inode, struct file *file)
829 struct proc_dir_entry *dp = PDE(inode);
833 rc = seq_open(file, &lnet_buffer_sops);
835 sf = file->private_data;
836 sf->private = dp->data;
842 static struct file_operations lnet_buffers_fops;
845 lnet_init_buffers_fops(void)
847 lnet_buffers_fops.owner = THIS_MODULE;
848 lnet_buffers_fops.llseek = seq_lseek;
849 lnet_buffers_fops.read = seq_read;
850 lnet_buffers_fops.open = lnet_buffer_seq_open;
851 lnet_buffers_fops.release = seq_release;
857 } lnet_ni_seq_iterator_t;
860 lnet_ni_seq_seek (lnet_ni_seq_iterator_t *lnsi, loff_t off)
867 lnsi->lnsi_ni = NULL;
874 if (lnsi->lnsi_ni == NULL ||
875 lnsi->lnsi_off > off) {
876 /* search from start */
880 /* continue search */
881 n = &lnsi->lnsi_ni->ni_list;
882 here = lnsi->lnsi_off;
885 lnsi->lnsi_off = off;
888 n = the_lnet.ln_nis.next;
890 while (n != &the_lnet.ln_nis) {
892 lnsi->lnsi_ni = list_entry(n, lnet_ni_t, ni_list);
900 lnsi->lnsi_ni = NULL;
908 lnet_ni_seq_start (struct seq_file *s, loff_t *pos)
910 lnet_ni_seq_iterator_t *lnsi;
913 LIBCFS_ALLOC(lnsi, sizeof(*lnsi));
917 lnsi->lnsi_ni = NULL;
918 rc = lnet_ni_seq_seek(lnsi, *pos);
922 LIBCFS_FREE(lnsi, sizeof(*lnsi));
927 lnet_ni_seq_stop (struct seq_file *s, void *iter)
929 lnet_ni_seq_iterator_t *lnsi = iter;
932 LIBCFS_FREE(lnsi, sizeof(*lnsi));
936 lnet_ni_seq_next (struct seq_file *s, void *iter, loff_t *pos)
938 lnet_ni_seq_iterator_t *lnsi = iter;
940 loff_t next = *pos + 1;
942 rc = lnet_ni_seq_seek(lnsi, next);
944 LIBCFS_FREE(lnsi, sizeof(*lnsi));
953 lnet_ni_seq_show (struct seq_file *s, void *iter)
955 lnet_ni_seq_iterator_t *lnsi = iter;
964 if (lnsi->lnsi_off == 0) {
965 seq_printf(s, "%-24s %4s %4s %5s %5s %5s\n",
966 "nid", "refs", "peer", "max", "tx", "min");
970 LASSERT (lnsi->lnsi_ni != NULL);
976 maxtxcr = ni->ni_maxtxcredits;
977 txcr = ni->ni_txcredits;
978 mintxcr = ni->ni_mintxcredits;
979 npeertxcr = ni->ni_peertxcredits;
981 nref = ni->ni_refcount;
985 seq_printf(s, "%-24s %4d %4d %5d %5d %5d\n",
986 libcfs_nid2str(nid), nref,
987 npeertxcr, maxtxcr, txcr, mintxcr);
991 static struct seq_operations lnet_ni_sops = {
992 /* start */ lnet_ni_seq_start,
993 /* stop */ lnet_ni_seq_stop,
994 /* next */ lnet_ni_seq_next,
995 /* show */ lnet_ni_seq_show,
999 lnet_ni_seq_open(struct inode *inode, struct file *file)
1001 struct proc_dir_entry *dp = PDE(inode);
1002 struct seq_file *sf;
1005 rc = seq_open(file, &lnet_ni_sops);
1007 sf = file->private_data;
1008 sf->private = dp->data;
1014 static struct file_operations lnet_ni_fops;
1017 lnet_init_ni_fops(void)
1019 lnet_ni_fops.owner = THIS_MODULE;
1020 lnet_ni_fops.llseek = seq_lseek;
1021 lnet_ni_fops.read = seq_read;
1022 lnet_ni_fops.open = lnet_ni_seq_open;
1023 lnet_ni_fops.release = seq_release;
1027 lnet_proc_init(void)
1029 struct proc_dir_entry *pde;
1031 /* Initialize LNET_PROC_STATS */
1032 pde = create_proc_entry (LNET_PROC_STATS, 0644, NULL);
1034 CERROR("couldn't create proc entry %s\n", LNET_PROC_STATS);
1039 pde->read_proc = lnet_router_proc_stats_read;
1040 pde->write_proc = lnet_router_proc_stats_write;
1042 /* Initialize LNET_PROC_ROUTES */
1043 pde = create_proc_entry (LNET_PROC_ROUTES, 0444, NULL);
1045 CERROR("couldn't create proc entry %s\n", LNET_PROC_ROUTES);
1049 lnet_init_routes_fops();
1050 pde->proc_fops = &lnet_routes_fops;
1053 /* Initialize LNET_PROC_ROUTERS */
1054 pde = create_proc_entry (LNET_PROC_ROUTERS, 0444, NULL);
1056 CERROR("couldn't create proc entry %s\n", LNET_PROC_ROUTERS);
1060 lnet_init_routers_fops();
1061 pde->proc_fops = &lnet_routers_fops;
1064 /* Initialize LNET_PROC_PEERS */
1065 pde = create_proc_entry (LNET_PROC_PEERS, 0444, NULL);
1067 CERROR("couldn't create proc entry %s\n", LNET_PROC_PEERS);
1071 lnet_init_peer_fops();
1072 pde->proc_fops = &lnet_peer_fops;
1075 /* Initialize LNET_PROC_BUFFERS */
1076 pde = create_proc_entry (LNET_PROC_BUFFERS, 0444, NULL);
1078 CERROR("couldn't create proc entry %s\n", LNET_PROC_BUFFERS);
1082 lnet_init_buffers_fops();
1083 pde->proc_fops = &lnet_buffers_fops;
1086 /* Initialize LNET_PROC_NIS */
1087 pde = create_proc_entry (LNET_PROC_NIS, 0444, NULL);
1089 CERROR("couldn't create proc entry %s\n", LNET_PROC_NIS);
1093 lnet_init_ni_fops();
1094 pde->proc_fops = &lnet_ni_fops;
1099 lnet_proc_fini(void)
1101 remove_proc_entry(LNET_PROC_STATS, 0);
1102 remove_proc_entry(LNET_PROC_ROUTES, 0);
1103 remove_proc_entry(LNET_PROC_ROUTERS, 0);
1104 remove_proc_entry(LNET_PROC_PEERS, 0);
1105 remove_proc_entry(LNET_PROC_BUFFERS, 0);
1106 remove_proc_entry(LNET_PROC_NIS, 0);
1112 lnet_proc_init(void)
1117 lnet_proc_fini(void)