2 * Copyright (C) 2009-2012, 2016 Cray, Inc.
4 * Copyright (c) 2013, 2015, Intel Corporation.
6 * Author: Nic Henke <nic@cray.com>
7 * Author: James Shimek <jshimek@cray.com>
9 * This file is part of Lustre, http://www.lustre.org.
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /* this code liberated and modified from lnet/lnet/router_proc.c */
27 #define DEBUG_SUBSYSTEM S_LND
29 #include <linux/seq_file.h>
30 #include <lprocfs_status.h>
32 #define GNILND_PROC_STATS "stats"
33 #define GNILND_PROC_MDD "mdd"
34 #define GNILND_PROC_SMSG "smsg"
35 #define GNILND_PROC_CONN "conn"
36 #define GNILND_PROC_PEER_CONNS "peer_conns"
37 #define GNILND_PROC_PEER "peer"
38 #define GNILND_PROC_CKSUM_TEST "cksum_test"
41 _kgnilnd_proc_run_cksum_test(int caseno, int nloops, int nob)
43 lnet_kiov_t *src, *dest;
44 struct timespec begin, end, diff;
51 LIBCFS_ALLOC(src, LNET_MAX_IOV * sizeof(lnet_kiov_t));
52 LIBCFS_ALLOC(dest, LNET_MAX_IOV * sizeof(lnet_kiov_t));
54 if (src == NULL || dest == NULL) {
55 CERROR("couldn't allocate iovs\n");
56 GOTO(unwind, rc = -ENOMEM);
59 for (i = 0; i < LNET_MAX_IOV; i++) {
60 src[i].kiov_offset = 0;
61 src[i].kiov_len = PAGE_SIZE;
62 src[i].kiov_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
64 if (src[i].kiov_page == NULL) {
65 CERROR("couldn't allocate page %d\n", i);
66 GOTO(unwind, rc = -ENOMEM);
69 dest[i].kiov_offset = 0;
70 dest[i].kiov_len = PAGE_SIZE;
71 dest[i].kiov_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
73 if (dest[i].kiov_page == NULL) {
74 CERROR("couldn't allocate page %d\n", i);
75 GOTO(unwind, rc = -ENOMEM);
79 /* add extra 2 pages - one for offset of src, 2nd to allow dest offset */
80 niov = (nob / PAGE_SIZE) + 2;
81 if (niov > LNET_MAX_IOV) {
82 CERROR("bytes %d too large, requires niov %d > %d\n",
83 nob, niov, LNET_MAX_IOV);
84 GOTO(unwind, rc = -E2BIG);
88 src[0].kiov_offset = 317;
89 dest[0].kiov_offset = 592;
96 dest[0].kiov_offset -= 1;
100 src[0].kiov_offset += 1;
104 src[0].kiov_offset += 1;
105 dest[0].kiov_offset -= 1;
107 src[0].kiov_len = PAGE_SIZE - src[0].kiov_offset;
108 dest[0].kiov_len = PAGE_SIZE - dest[0].kiov_offset;
110 for (i = 0; i < niov; i++) {
111 memset(page_address(src[i].kiov_page) + src[i].kiov_offset,
112 0xf0 + i, src[i].kiov_len);
115 lnet_copy_kiov2kiov(niov, dest, 0, niov, src, 0, nob);
117 getnstimeofday(&begin);
119 for (n = 0; n < nloops; n++) {
120 CDEBUG(D_BUFFS, "case %d loop %d src %d dest %d nob %d niov %d\n",
121 caseno, n, src[0].kiov_offset, dest[0].kiov_offset, nob, niov);
122 cksum = kgnilnd_cksum_kiov(niov, src, 0, nob - (n % nob), 1);
123 cksum2 = kgnilnd_cksum_kiov(niov, dest, 0, nob - (n % nob), 1);
125 if (cksum != cksum2) {
126 CERROR("case %d loop %d different checksums %x expected %x\n",
127 j, n, cksum2, cksum);
128 GOTO(unwind, rc = -ENOKEY);
132 getnstimeofday(&end);
134 mbytes = ((__u64)nloops * nob * 2) / (1024*1024);
136 diff = kgnilnd_ts_sub(end, begin);
138 LCONSOLE_INFO("running %lldMB took %ld.%ld seconds\n",
139 mbytes, diff.tv_sec, diff.tv_nsec);
142 CDEBUG(D_NET, "freeing %d pages\n", i);
143 for (i -= 1; i >= 0; i--) {
144 if (src[i].kiov_page != NULL) {
145 __free_page(src[i].kiov_page);
147 if (dest[i].kiov_page != NULL) {
148 __free_page(dest[i].kiov_page);
153 LIBCFS_FREE(src, LNET_MAX_IOV * sizeof(lnet_kiov_t));
155 LIBCFS_FREE(dest, LNET_MAX_IOV * sizeof(lnet_kiov_t));
160 kgnilnd_proc_cksum_test_write(struct file *file, const char __user *ubuffer,
161 size_t count, loff_t *ppos)
163 char dummy[256 + 1] = { '\0' };
164 int testno, nloops, nbytes;
168 if (kgnilnd_data.kgn_init < GNILND_INIT_ALL) {
169 CERROR("can't run cksum test, kgnilnd is not initialized yet\n");
173 if (count >= sizeof(dummy) || count == 0)
176 if (copy_from_user(dummy, ubuffer, count))
179 if (sscanf(dummy, "%d:%d:%d", &testno, &nloops, &nbytes) == 3) {
180 rc = _kgnilnd_proc_run_cksum_test(testno, nloops, nbytes);
184 /* spurious, but lets us know the parse was ok */
192 kgnilnd_cksum_test_seq_open(struct inode *inode, struct file *file)
194 return single_open(file, NULL, PDE_DATA(inode));
197 static const struct file_operations kgn_cksum_test_fops = {
198 .owner = THIS_MODULE,
199 .open = kgnilnd_cksum_test_seq_open,
200 .write = kgnilnd_proc_cksum_test_write,
202 .release = seq_release,
206 kgnilnd_stats_seq_show(struct seq_file *sf, void *v)
211 if (kgnilnd_data.kgn_init < GNILND_INIT_ALL) {
212 seq_printf(sf, "kgnilnd is not initialized yet\n");
216 /* only do the first device */
217 dev = &kgnilnd_data.kgn_devices[0];
219 /* sampling is racy, but so is reading this file! */
221 do_gettimeofday(&now);
223 seq_printf(sf, "time: %lu.%lu\n"
232 "n_eager_allocs: %d\n"
233 "GART map bytes: %ld\n"
234 "TX queued maps: %d\n"
235 "TX phys nmaps: %d\n"
236 "TX phys bytes: %lu\n"
237 "TX virt nmaps: %d\n"
238 "TX virt bytes: %llu\n"
239 "RDMAQ bytes_auth: %ld\n"
240 "RDMAQ bytes_left: %ld\n"
241 "RDMAQ nstalls: %d\n"
242 "dev mutex delay: %ld\n"
244 "dev n_schedule: %d\n"
245 "SMSG fast_try: %d\n"
247 "SMSG fast_block: %d\n"
249 "SMSG tx_bytes: %lu\n"
251 "SMSG rx_bytes: %lu\n"
253 "RDMA tx_bytes: %lu\n"
255 "RDMA rx_bytes: %lu\n"
259 "RDMA REV length: %d\n"
260 "RDMA REV offset: %d\n"
261 "RDMA REV copy: %d\n",
262 now.tv_sec, now.tv_usec,
263 atomic_read(&kgnilnd_data.kgn_ntx),
264 atomic_read(&kgnilnd_data.kgn_npeers),
265 atomic_read(&kgnilnd_data.kgn_nconns),
266 atomic_read(&dev->gnd_neps),
267 atomic_read(&dev->gnd_ndgrams),
268 atomic_read(&dev->gnd_nfmablk),
269 atomic_read(&dev->gnd_n_mdd), atomic_read(&dev->gnd_n_mdd_held),
270 atomic_read(&kgnilnd_data.kgn_neager_allocs),
271 atomic64_read(&dev->gnd_nbytes_map),
272 atomic_read(&dev->gnd_nq_map),
273 dev->gnd_map_nphys, dev->gnd_map_physnop * PAGE_SIZE,
274 dev->gnd_map_nvirt, dev->gnd_map_virtnob,
275 atomic64_read(&dev->gnd_rdmaq_bytes_out),
276 atomic64_read(&dev->gnd_rdmaq_bytes_ok),
277 atomic_read(&dev->gnd_rdmaq_nstalls),
278 dev->gnd_mutex_delay,
279 atomic_read(&dev->gnd_n_yield),
280 atomic_read(&dev->gnd_n_schedule),
281 atomic_read(&dev->gnd_fast_try),
282 atomic_read(&dev->gnd_fast_ok),
283 atomic_read(&dev->gnd_fast_block),
284 atomic_read(&dev->gnd_short_ntx),
285 atomic64_read(&dev->gnd_short_txbytes),
286 atomic_read(&dev->gnd_short_nrx),
287 atomic64_read(&dev->gnd_short_rxbytes),
288 atomic_read(&dev->gnd_rdma_ntx),
289 atomic64_read(&dev->gnd_rdma_txbytes),
290 atomic_read(&dev->gnd_rdma_nrx),
291 atomic64_read(&dev->gnd_rdma_rxbytes),
292 atomic_read(&kgnilnd_data.kgn_nvmap_short),
293 atomic_read(&kgnilnd_data.kgn_nvmap_cksum),
294 atomic_read(&kgnilnd_data.kgn_nkmap_short),
295 atomic_read(&kgnilnd_data.kgn_rev_length),
296 atomic_read(&kgnilnd_data.kgn_rev_offset),
297 atomic_read(&kgnilnd_data.kgn_rev_copy_buff));
303 kgnilnd_proc_stats_write(struct file *file, const char __user *ubuffer,
304 size_t count, loff_t *ppos)
308 if (kgnilnd_data.kgn_init < GNILND_INIT_ALL) {
309 CERROR("kgnilnd is not initialized for stats write\n");
313 /* only do the first device */
314 dev = &kgnilnd_data.kgn_devices[0];
316 atomic_set(&dev->gnd_short_ntx, 0);
317 atomic_set(&dev->gnd_short_nrx, 0);
318 atomic64_set(&dev->gnd_short_txbytes, 0);
319 atomic64_set(&dev->gnd_short_rxbytes, 0);
320 atomic_set(&dev->gnd_rdma_ntx, 0);
321 atomic_set(&dev->gnd_rdma_nrx, 0);
322 atomic_set(&dev->gnd_fast_ok, 0);
323 atomic_set(&dev->gnd_fast_try, 0);
324 atomic_set(&dev->gnd_fast_block, 0);
325 atomic64_set(&dev->gnd_rdma_txbytes, 0);
326 atomic64_set(&dev->gnd_rdma_rxbytes, 0);
327 atomic_set(&dev->gnd_rdmaq_nstalls, 0);
328 set_mb(dev->gnd_mutex_delay, 0);
329 atomic_set(&dev->gnd_n_yield, 0);
330 atomic_set(&dev->gnd_n_schedule, 0);
331 atomic_set(&kgnilnd_data.kgn_nvmap_short, 0);
332 atomic_set(&kgnilnd_data.kgn_nvmap_cksum, 0);
333 atomic_set(&kgnilnd_data.kgn_nkmap_short, 0);
334 /* sampling is racy, but so is writing this file! */
340 kgnilnd_stats_seq_open(struct inode *inode, struct file *file)
342 return single_open(file, kgnilnd_stats_seq_show, PDE_DATA(inode));
345 static const struct file_operations kgn_stats_fops = {
346 .owner = THIS_MODULE,
347 .open = kgnilnd_stats_seq_open,
349 .write = kgnilnd_proc_stats_write,
351 .release = seq_release,
355 kgn_device_t *gmdd_dev;
358 } kgn_mdd_seq_iter_t;
361 kgnilnd_mdd_seq_seek(kgn_mdd_seq_iter_t *gseq, loff_t off)
369 gseq->gmdd_tx = NULL;
376 if (tx == NULL || gseq->gmdd_off > off) {
377 /* search from start */
378 r = gseq->gmdd_dev->gnd_map_list.next;
381 /* continue current search */
382 r = &tx->tx_map_list;
383 here = gseq->gmdd_off;
386 gseq->gmdd_off = off;
388 while (r != &gseq->gmdd_dev->gnd_map_list) {
391 t = list_entry(r, kgn_tx_t, tx_map_list);
402 gseq->gmdd_tx = NULL;
409 kgnilnd_mdd_seq_start(struct seq_file *s, loff_t *pos)
412 kgn_mdd_seq_iter_t *gseq;
415 if (kgnilnd_data.kgn_init < GNILND_INIT_ALL) {
419 LIBCFS_ALLOC(gseq, sizeof(*gseq));
421 CERROR("could not allocate mdd sequence iterator\n");
425 /* only doing device 0 for now */
426 gseq->gmdd_dev = &kgnilnd_data.kgn_devices[0];
427 gseq->gmdd_tx = NULL;
429 /* need to lock map while we poke - huge disturbance
430 * but without it, no way to get the data printed */
431 spin_lock(&gseq->gmdd_dev->gnd_map_lock);
433 /* set private to gseq for stop */
436 rc = kgnilnd_mdd_seq_seek(gseq, *pos);
444 kgnilnd_mdd_seq_stop(struct seq_file *s, void *iter)
446 kgn_mdd_seq_iter_t *gseq = s->private;
449 spin_unlock(&gseq->gmdd_dev->gnd_map_lock);
450 LIBCFS_FREE(gseq, sizeof(*gseq));
455 kgnilnd_mdd_seq_next(struct seq_file *s, void *iter, loff_t *pos)
457 kgn_mdd_seq_iter_t *gseq = iter;
459 loff_t next = *pos + 1;
461 rc = kgnilnd_mdd_seq_seek(gseq, next);
470 kgnilnd_mdd_seq_show(struct seq_file *s, void *iter)
472 kgn_mdd_seq_iter_t *gseq = iter;
478 gni_mem_handle_t hndl;
480 if (gseq->gmdd_off == 0) {
481 seq_printf(s, "%s %22s %16s %8s %8s %37s\n",
482 "tx", "tx_id", "nob", "physnop",
483 "buftype", "mem handle");
490 id = tx->tx_id.txe_smsg_id;
492 physnop = tx->tx_phys_npages;
493 buftype = tx->tx_buftype;
494 hndl.qword1 = tx->tx_map_key.qword1;
495 hndl.qword2 = tx->tx_map_key.qword2;
497 seq_printf(s, "%p %x %16llu %8d %#8x %#llx.%#llxx\n",
498 tx, id, nob, physnop, buftype,
499 hndl.qword1, hndl.qword2);
504 static struct seq_operations kgn_mdd_sops = {
505 .start = kgnilnd_mdd_seq_start,
506 .stop = kgnilnd_mdd_seq_stop,
507 .next = kgnilnd_mdd_seq_next,
508 .show = kgnilnd_mdd_seq_show,
513 kgnilnd_mdd_seq_open(struct inode *inode, struct file *file)
518 rc = seq_open(file, &kgn_mdd_sops);
520 sf = file->private_data;
522 /* NULL means we've not yet open() */
528 static struct file_operations kgn_mdd_fops = {
529 .owner = THIS_MODULE,
530 .open = kgnilnd_mdd_seq_open,
533 .release = seq_release,
538 kgn_device_t *gsmsg_dev;
539 kgn_fma_memblock_t *gsmsg_fmablk;
541 } kgn_smsg_seq_iter_t;
544 kgnilnd_smsg_seq_seek(kgn_smsg_seq_iter_t *gseq, loff_t off)
546 kgn_fma_memblock_t *fmablk;
552 /* offset 0 is the header, so we start real entries at
553 * here == off == 1 */
555 gseq->gsmsg_fmablk = NULL;
560 fmablk = gseq->gsmsg_fmablk;
561 dev = gseq->gsmsg_dev;
563 spin_lock(&dev->gnd_fmablk_lock);
565 if (fmablk != NULL &&
566 gseq->gsmsg_version != atomic_read(&dev->gnd_fmablk_vers)) {
572 if (fmablk == NULL || gseq->gsmsg_off > off) {
573 /* search from start */
574 r = dev->gnd_fma_buffs.next;
577 /* continue current search */
578 r = &fmablk->gnm_bufflist;
579 here = gseq->gsmsg_off;
582 gseq->gsmsg_version = atomic_read(&dev->gnd_fmablk_vers);
583 gseq->gsmsg_off = off;
585 while (r != &dev->gnd_fma_buffs) {
586 kgn_fma_memblock_t *t;
588 t = list_entry(r, kgn_fma_memblock_t, gnm_bufflist);
591 gseq->gsmsg_fmablk = t;
599 gseq->gsmsg_fmablk = NULL;
602 spin_unlock(&dev->gnd_fmablk_lock);
607 kgnilnd_smsg_seq_start(struct seq_file *s, loff_t *pos)
610 kgn_smsg_seq_iter_t *gseq;
613 if (kgnilnd_data.kgn_init < GNILND_INIT_ALL) {
617 LIBCFS_ALLOC(gseq, sizeof(*gseq));
619 CERROR("could not allocate smsg sequence iterator\n");
623 /* only doing device 0 for now */
624 gseq->gsmsg_dev = &kgnilnd_data.kgn_devices[0];
625 gseq->gsmsg_fmablk = NULL;
626 rc = kgnilnd_smsg_seq_seek(gseq, *pos);
630 LIBCFS_FREE(gseq, sizeof(*gseq));
635 kgnilnd_smsg_seq_stop(struct seq_file *s, void *iter)
637 kgn_smsg_seq_iter_t *gseq = iter;
640 LIBCFS_FREE(gseq, sizeof(*gseq));
644 kgnilnd_smsg_seq_next(struct seq_file *s, void *iter, loff_t *pos)
646 kgn_smsg_seq_iter_t *gseq = iter;
648 loff_t next = *pos + 1;
650 rc = kgnilnd_smsg_seq_seek(gseq, next);
652 LIBCFS_FREE(gseq, sizeof(*gseq));
660 kgnilnd_smsg_seq_show(struct seq_file *s, void *iter)
662 kgn_smsg_seq_iter_t *gseq = iter;
663 kgn_fma_memblock_t *fmablk;
665 int avail_mboxs, held_mboxs, num_mboxs;
666 unsigned int blk_size;
668 kgn_fmablk_state_t state;
669 gni_mem_handle_t hndl;
671 if (gseq->gsmsg_off == 0) {
672 seq_printf(s, "%5s %4s %6s/%5s/%5s %9s %18s %37s\n",
673 "blk#", "type", "avail", "held", "total", "size",
674 "fmablk", "mem handle");
678 fmablk = gseq->gsmsg_fmablk;
679 dev = gseq->gsmsg_dev;
680 LASSERT(fmablk != NULL);
682 spin_lock(&dev->gnd_fmablk_lock);
684 if (gseq->gsmsg_version != atomic_read(&dev->gnd_fmablk_vers)) {
686 spin_unlock(&dev->gnd_fmablk_lock);
690 live = fmablk->gnm_hold_timeout == 0;
691 /* none are available if it isn't live... */
692 avail_mboxs = live ? fmablk->gnm_avail_mboxs : 0;
693 held_mboxs = fmablk->gnm_held_mboxs;
694 num_mboxs = fmablk->gnm_num_mboxs;
695 blk_size = fmablk->gnm_blk_size;
696 state = fmablk->gnm_state;
697 hndl.qword1 = fmablk->gnm_hndl.qword1;
698 hndl.qword2 = fmablk->gnm_hndl.qword2;
700 spin_unlock(&dev->gnd_fmablk_lock);
703 seq_printf(s, "%5d %4s %6d/%5d/%5d %9d %18p %#llx.%#llx\n",
704 (int) gseq->gsmsg_off, kgnilnd_fmablk_state2str(state),
705 avail_mboxs, held_mboxs, num_mboxs, blk_size,
706 fmablk, hndl.qword1, hndl.qword2);
708 seq_printf(s, "%5d %4s %6d/%5d/%5d %9d %18p %37s\n",
709 (int) gseq->gsmsg_off, kgnilnd_fmablk_state2str(state),
710 avail_mboxs, held_mboxs, num_mboxs, blk_size,
711 fmablk, "PURGATORY.HOLD");
717 static struct seq_operations kgn_smsg_sops = {
718 .start = kgnilnd_smsg_seq_start,
719 .stop = kgnilnd_smsg_seq_stop,
720 .next = kgnilnd_smsg_seq_next,
721 .show = kgnilnd_smsg_seq_show,
726 kgnilnd_smsg_seq_open(struct inode *inode, struct file *file)
731 rc = seq_open(file, &kgn_smsg_sops);
733 sf = file->private_data;
734 sf->private = PDE_DATA(inode);
740 static struct file_operations kgn_smsg_fops = {
741 .owner = THIS_MODULE,
742 .open = kgnilnd_smsg_seq_open,
745 .release = seq_release,
750 struct list_head *gconn_list;
751 kgn_conn_t *gconn_conn;
754 } kgn_conn_seq_iter_t;
757 kgnilnd_conn_seq_seek(kgn_conn_seq_iter_t *gseq, loff_t off)
759 struct list_head *list, *tmp;
764 gseq->gconn_hashidx = 0;
765 gseq->gconn_list = NULL;
768 if (off > atomic_read(&kgnilnd_data.kgn_nconns)) {
769 gseq->gconn_list = NULL;
773 read_lock(&kgnilnd_data.kgn_peer_conn_lock);
774 if (gseq->gconn_list != NULL &&
775 gseq->gconn_version != kgnilnd_data.kgn_conn_version) {
781 if ((gseq->gconn_list == NULL) ||
782 (gseq->gconn_off > off) ||
783 (gseq->gconn_hashidx >= *kgnilnd_tunables.kgn_peer_hash_size)) {
784 /* search from start */
785 gseq->gconn_hashidx = 0;
786 list = &kgnilnd_data.kgn_conns[gseq->gconn_hashidx];
789 /* continue current search */
790 list = gseq->gconn_list;
793 gseq->gconn_version = kgnilnd_data.kgn_conn_version;
794 gseq->gconn_off = off;
798 list_for_each(tmp, list) {
801 conn = list_entry(tmp, kgn_conn_t, gnc_hashlist);
802 gseq->gconn_conn = conn;
808 /* if we got through this hash bucket with 'off' still to go, try next*/
809 gseq->gconn_hashidx++;
811 (gseq->gconn_hashidx < *kgnilnd_tunables.kgn_peer_hash_size)) {
812 list = &kgnilnd_data.kgn_conns[gseq->gconn_hashidx];
816 gseq->gconn_list = NULL;
819 read_unlock(&kgnilnd_data.kgn_peer_conn_lock);
824 kgnilnd_conn_seq_start(struct seq_file *s, loff_t *pos)
827 kgn_conn_seq_iter_t *gseq;
830 if (kgnilnd_data.kgn_init < GNILND_INIT_ALL) {
834 LIBCFS_ALLOC(gseq, sizeof(*gseq));
836 CERROR("could not allocate conn sequence iterator\n");
840 /* only doing device 0 for now */
841 gseq->gconn_list = NULL;
842 rc = kgnilnd_conn_seq_seek(gseq, *pos);
846 LIBCFS_FREE(gseq, sizeof(*gseq));
851 kgnilnd_conn_seq_stop(struct seq_file *s, void *iter)
853 kgn_conn_seq_iter_t *gseq = iter;
856 LIBCFS_FREE(gseq, sizeof(*gseq));
860 kgnilnd_conn_seq_next(struct seq_file *s, void *iter, loff_t *pos)
862 kgn_conn_seq_iter_t *gseq = iter;
864 loff_t next = *pos + 1;
866 rc = kgnilnd_conn_seq_seek(gseq, next);
868 LIBCFS_FREE(gseq, sizeof(*gseq));
876 kgnilnd_conn_seq_show(struct seq_file *s, void *iter)
878 kgn_conn_seq_iter_t *gseq = iter;
879 kgn_peer_t *peer = NULL;
882 /* there is no header data for conns, so offset 0 is the first
885 conn = gseq->gconn_conn;
886 LASSERT(conn != NULL);
888 read_lock(&kgnilnd_data.kgn_peer_conn_lock);
889 if (gseq->gconn_list != NULL &&
890 gseq->gconn_version != kgnilnd_data.kgn_conn_version) {
892 read_unlock(&kgnilnd_data.kgn_peer_conn_lock);
896 /* instead of saving off the data, just refcount */
897 kgnilnd_conn_addref(conn);
898 if (conn->gnc_peer) {
899 /* don't use link - after unlock it could get nuked */
900 peer = conn->gnc_peer;
901 kgnilnd_peer_addref(peer);
904 read_unlock(&kgnilnd_data.kgn_peer_conn_lock);
906 seq_printf(s, "%p->%s [%d] q %d/%d/%d "
907 "tx sq %u %dms/%dms "
908 "rx sq %u %dms/%dms "
909 "noop r/s %d/%d w/s/cq %lds/%lds/%lds "
910 "sched a/d %lds/%lds "
911 "tx_re %lld TO %ds %s\n",
912 conn, peer ? libcfs_nid2str(peer->gnp_nid) : "<?>",
913 atomic_read(&conn->gnc_refcount),
914 kgnilnd_count_list(&conn->gnc_fmaq),
915 atomic_read(&conn->gnc_nlive_fma),
916 atomic_read(&conn->gnc_nlive_rdma),
917 atomic_read(&conn->gnc_tx_seq),
918 jiffies_to_msecs(jiffies - conn->gnc_last_tx),
919 jiffies_to_msecs(jiffies - conn->gnc_last_tx_cq),
920 atomic_read(&conn->gnc_rx_seq),
921 jiffies_to_msecs(jiffies - conn->gnc_last_rx),
922 jiffies_to_msecs(jiffies - conn->gnc_last_rx_cq),
923 atomic_read(&conn->gnc_reaper_noop),
924 atomic_read(&conn->gnc_sched_noop),
925 cfs_duration_sec(jiffies - conn->gnc_last_noop_want),
926 cfs_duration_sec(jiffies - conn->gnc_last_noop_sent),
927 cfs_duration_sec(jiffies - conn->gnc_last_noop_cq),
928 cfs_duration_sec(jiffies - conn->gnc_last_sched_ask),
929 cfs_duration_sec(jiffies - conn->gnc_last_sched_do),
930 conn->gnc_tx_retrans, conn->gnc_timeout,
931 kgnilnd_conn_state2str(conn));
934 kgnilnd_peer_decref(peer);
935 kgnilnd_conn_decref(conn);
940 static struct seq_operations kgn_conn_sops = {
941 .start = kgnilnd_conn_seq_start,
942 .stop = kgnilnd_conn_seq_stop,
943 .next = kgnilnd_conn_seq_next,
944 .show = kgnilnd_conn_seq_show,
948 #define KGN_DEBUG_PEER_NID_DEFAULT -1
949 static int kgnilnd_debug_peer_nid = KGN_DEBUG_PEER_NID_DEFAULT;
952 kgnilnd_proc_peer_conns_write(struct file *file, const char __user *ubuffer,
953 size_t count, loff_t *ppos)
958 if (count >= sizeof(dummy) || count == 0)
961 if (copy_from_user(dummy, ubuffer, count))
964 rc = sscanf(dummy, "%d", &kgnilnd_debug_peer_nid);
973 /* debug data to print from conns associated with peer nid
976 - mbox_addr (msg_buffer + mbox_offset)
995 kgnilnd_proc_peer_conns_seq_show(struct seq_file *sf, void *v)
1000 struct timespec now;
1003 if (kgnilnd_debug_peer_nid == KGN_DEBUG_PEER_NID_DEFAULT) {
1004 seq_printf(sf, "peer_conns not initialized\n");
1008 /* sample date/time stamp - print time in UTC
1009 * 2012-12-11T16:06:16.966751 123@gni ...
1011 getnstimeofday(&now);
1012 time_to_tm(now.tv_sec, 0, &ctm);
1015 write_lock(&kgnilnd_data.kgn_peer_conn_lock);
1016 peer = kgnilnd_find_peer_locked(kgnilnd_debug_peer_nid);
1019 seq_printf(sf, "peer not found for this nid %d\n",
1020 kgnilnd_debug_peer_nid);
1021 write_unlock(&kgnilnd_data.kgn_peer_conn_lock);
1025 list_for_each_entry(conn, &peer->gnp_conns, gnc_list) {
1027 "%04ld-%02d-%02dT%02d:%02d:%02d.%06ld %s "
1033 "err %d peer err %d "
1034 "tx sq %u %dms/%dms "
1035 "rx sq %u %dms/%dms/%dms "
1037 ctm.tm_year+1900, ctm.tm_mon+1, ctm.tm_mday,
1038 ctm.tm_hour, ctm.tm_min, ctm.tm_sec, now.tv_nsec,
1039 libcfs_nid2str(peer->gnp_nid),
1040 conn->remote_mbox_addr,
1041 kgnilnd_conn_dgram_type2str(conn->gnc_dgram_type),
1042 kgnilnd_conn_state2str(conn),
1043 conn->gnc_in_purgatory,
1044 conn->gnc_close_sent,
1045 conn->gnc_close_recvd,
1047 conn->gnc_peer_error,
1048 atomic_read(&conn->gnc_tx_seq),
1049 jiffies_to_msecs(jifs - conn->gnc_last_tx),
1050 jiffies_to_msecs(jifs - conn->gnc_last_tx_cq),
1051 atomic_read(&conn->gnc_rx_seq),
1052 jiffies_to_msecs(jifs - conn->gnc_first_rx),
1053 jiffies_to_msecs(jifs - conn->gnc_last_rx),
1054 jiffies_to_msecs(jifs - conn->gnc_last_rx_cq),
1055 conn->gnc_tx_retrans);
1058 write_unlock(&kgnilnd_data.kgn_peer_conn_lock);
1063 kgnilnd_peer_conns_seq_open(struct inode *inode, struct file *file)
1065 return single_open(file, kgnilnd_proc_peer_conns_seq_show,
1069 static const struct file_operations kgn_peer_conns_fops = {
1070 .owner = THIS_MODULE,
1071 .open = kgnilnd_peer_conns_seq_open,
1073 .write = kgnilnd_proc_peer_conns_write,
1074 .llseek = seq_lseek,
1075 .release = seq_release,
1079 kgnilnd_conn_seq_open(struct inode *inode, struct file *file)
1081 struct seq_file *sf;
1084 rc = seq_open(file, &kgn_conn_sops);
1086 sf = file->private_data;
1087 sf->private = PDE_DATA(inode);
1093 static struct file_operations kgn_conn_fops = {
1094 .owner = THIS_MODULE,
1095 .open = kgnilnd_conn_seq_open,
1097 .llseek = seq_lseek,
1098 .release = seq_release,
1102 __u64 gpeer_version;
1103 struct list_head *gpeer_list;
1104 kgn_peer_t *gpeer_peer;
1107 } kgn_peer_seq_iter_t;
1110 kgnilnd_peer_seq_seek(kgn_peer_seq_iter_t *gseq, loff_t off)
1112 struct list_head *list, *tmp;
1117 gseq->gpeer_hashidx = 0;
1118 gseq->gpeer_list = NULL;
1121 if (off > atomic_read(&kgnilnd_data.kgn_npeers)) {
1122 gseq->gpeer_list = NULL;
1126 read_lock(&kgnilnd_data.kgn_peer_conn_lock);
1127 if (gseq->gpeer_list != NULL &&
1128 gseq->gpeer_version != kgnilnd_data.kgn_peer_version) {
1134 if ((gseq->gpeer_list == NULL) ||
1135 (gseq->gpeer_off > off) ||
1136 (gseq->gpeer_hashidx >= *kgnilnd_tunables.kgn_peer_hash_size)) {
1137 /* search from start */
1138 gseq->gpeer_hashidx = 0;
1139 list = &kgnilnd_data.kgn_peers[gseq->gpeer_hashidx];
1142 /* continue current search */
1143 list = gseq->gpeer_list;
1146 gseq->gpeer_version = kgnilnd_data.kgn_peer_version;
1147 gseq->gpeer_off = off;
1151 list_for_each(tmp, list) {
1154 peer = list_entry(tmp, kgn_peer_t, gnp_list);
1155 gseq->gpeer_peer = peer;
1161 /* if we got through this hash bucket with 'off' still to go, try next*/
1162 gseq->gpeer_hashidx++;
1163 if ((here <= off) &&
1164 (gseq->gpeer_hashidx < *kgnilnd_tunables.kgn_peer_hash_size)) {
1165 list = &kgnilnd_data.kgn_peers[gseq->gpeer_hashidx];
1169 gseq->gpeer_list = NULL;
1172 read_unlock(&kgnilnd_data.kgn_peer_conn_lock);
1177 kgnilnd_peer_seq_start(struct seq_file *s, loff_t *pos)
1180 kgn_peer_seq_iter_t *gseq;
1183 if (kgnilnd_data.kgn_init < GNILND_INIT_ALL) {
1187 LIBCFS_ALLOC(gseq, sizeof(*gseq));
1189 CERROR("could not allocate peer sequence iterator\n");
1193 /* only doing device 0 for now */
1194 gseq->gpeer_list = NULL;
1195 rc = kgnilnd_peer_seq_seek(gseq, *pos);
1199 LIBCFS_FREE(gseq, sizeof(*gseq));
1204 kgnilnd_peer_seq_stop(struct seq_file *s, void *iter)
1206 kgn_peer_seq_iter_t *gseq = iter;
1209 LIBCFS_FREE(gseq, sizeof(*gseq));
1213 kgnilnd_peer_seq_next(struct seq_file *s, void *iter, loff_t *pos)
1215 kgn_peer_seq_iter_t *gseq = iter;
1217 loff_t next = *pos + 1;
1219 rc = kgnilnd_peer_seq_seek(gseq, next);
1221 LIBCFS_FREE(gseq, sizeof(*gseq));
1229 kgnilnd_peer_seq_show(struct seq_file *s, void *iter)
1231 kgn_peer_seq_iter_t *gseq = iter;
1236 /* there is no header data for peers, so offset 0 is the first
1239 peer = gseq->gpeer_peer;
1240 LASSERT(peer != NULL);
1242 read_lock(&kgnilnd_data.kgn_peer_conn_lock);
1243 if (gseq->gpeer_list != NULL &&
1244 gseq->gpeer_version != kgnilnd_data.kgn_peer_version) {
1246 read_unlock(&kgnilnd_data.kgn_peer_conn_lock);
1250 /* instead of saving off the data, just refcount */
1251 kgnilnd_peer_addref(peer);
1252 conn = kgnilnd_find_conn_locked(peer);
1254 if (peer->gnp_connecting) {
1256 } else if (conn != NULL) {
1262 list_for_each_entry(conn, &peer->gnp_conns, gnc_list) {
1263 if (conn->gnc_in_purgatory) {
1268 read_unlock(&kgnilnd_data.kgn_peer_conn_lock);
1270 seq_printf(s, "%p->%s [%d] %s NIC 0x%x q %d conn %c purg %d last %d@%lldms dgram %d@%dms reconn %dms to %lus \n",
1271 peer, libcfs_nid2str(peer->gnp_nid),
1272 atomic_read(&peer->gnp_refcount),
1273 (peer->gnp_state == GNILND_PEER_DOWN) ? "down" :
1274 peer->gnp_state == GNILND_PEER_TIMED_OUT ? "timedout" : "up",
1276 kgnilnd_count_list(&peer->gnp_tx_queue),
1279 peer->gnp_last_errno,
1280 (ktime_get_seconds() - peer->gnp_last_alive) * MSEC_PER_SEC,
1281 peer->gnp_last_dgram_errno,
1282 jiffies_to_msecs(jiffies - peer->gnp_last_dgram_time),
1283 peer->gnp_reconnect_interval != 0
1284 ? jiffies_to_msecs(jiffies - peer->gnp_reconnect_time)
1286 peer->gnp_reconnect_interval);
1288 kgnilnd_peer_decref(peer);
1293 static struct seq_operations kgn_peer_sops = {
1294 .start = kgnilnd_peer_seq_start,
1295 .stop = kgnilnd_peer_seq_stop,
1296 .next = kgnilnd_peer_seq_next,
1297 .show = kgnilnd_peer_seq_show,
1301 kgnilnd_peer_seq_open(struct inode *inode, struct file *file)
1303 struct seq_file *sf;
1306 rc = seq_open(file, &kgn_peer_sops);
1308 sf = file->private_data;
1309 sf->private = PDE_DATA(inode);
1315 static struct file_operations kgn_peer_fops = {
1316 .owner = THIS_MODULE,
1317 .open = kgnilnd_peer_seq_open,
1319 .llseek = seq_lseek,
1320 .release = seq_release,
1323 static struct proc_dir_entry *kgn_proc_root;
1326 kgnilnd_proc_init(void)
1328 struct proc_dir_entry *pde;
1333 kgn_proc_root = proc_mkdir(libcfs_lnd2modname(GNILND), NULL);
1334 if (kgn_proc_root == NULL) {
1335 CERROR("couldn't create proc dir %s\n",
1336 libcfs_lnd2modname(GNILND));
1340 /* Initialize CKSUM_TEST */
1341 pde = proc_create(GNILND_PROC_CKSUM_TEST, 0200, kgn_proc_root,
1342 &kgn_cksum_test_fops);
1344 CERROR("couldn't create proc entry %s\n", GNILND_PROC_CKSUM_TEST);
1345 GOTO(remove_dir, rc = -ENOENT);
1348 /* Initialize STATS */
1349 pde = proc_create(GNILND_PROC_STATS, 0644, kgn_proc_root,
1352 CERROR("couldn't create proc entry %s\n", GNILND_PROC_STATS);
1353 GOTO(remove_test, rc = -ENOENT);
1356 /* Initialize MDD */
1357 pde = proc_create(GNILND_PROC_MDD, 0444, kgn_proc_root, &kgn_mdd_fops);
1359 CERROR("couldn't create proc entry %s\n", GNILND_PROC_MDD);
1360 GOTO(remove_stats, rc = -ENOENT);
1363 /* Initialize SMSG */
1364 pde = proc_create(GNILND_PROC_SMSG, 0444, kgn_proc_root,
1367 CERROR("couldn't create proc entry %s\n", GNILND_PROC_SMSG);
1368 GOTO(remove_mdd, rc = -ENOENT);
1371 /* Initialize CONN */
1372 pde = proc_create(GNILND_PROC_CONN, 0444, kgn_proc_root,
1375 CERROR("couldn't create proc entry %s\n", GNILND_PROC_CONN);
1376 GOTO(remove_smsg, rc = -ENOENT);
1379 /* Initialize peer conns debug */
1380 pde = proc_create(GNILND_PROC_PEER_CONNS, 0644, kgn_proc_root,
1381 &kgn_peer_conns_fops);
1383 CERROR("couldn't create proc entry %s\n", GNILND_PROC_PEER_CONNS);
1384 GOTO(remove_conn, rc = -ENOENT);
1387 /* Initialize PEER */
1388 pde = proc_create(GNILND_PROC_PEER, 0444, kgn_proc_root,
1391 CERROR("couldn't create proc entry %s\n", GNILND_PROC_PEER);
1392 GOTO(remove_pc, rc = -ENOENT);
1397 remove_proc_entry(GNILND_PROC_PEER_CONNS, kgn_proc_root);
1399 remove_proc_entry(GNILND_PROC_CONN, kgn_proc_root);
1401 remove_proc_entry(GNILND_PROC_SMSG, kgn_proc_root);
1403 remove_proc_entry(GNILND_PROC_MDD, kgn_proc_root);
1405 remove_proc_entry(GNILND_PROC_STATS, kgn_proc_root);
1407 remove_proc_entry(GNILND_PROC_CKSUM_TEST, kgn_proc_root);
1409 remove_proc_entry(libcfs_lnd2modname(GNILND), NULL);
1415 kgnilnd_proc_fini(void)
1417 remove_proc_entry(GNILND_PROC_PEER_CONNS, kgn_proc_root);
1418 remove_proc_entry(GNILND_PROC_PEER, kgn_proc_root);
1419 remove_proc_entry(GNILND_PROC_CONN, kgn_proc_root);
1420 remove_proc_entry(GNILND_PROC_MDD, kgn_proc_root);
1421 remove_proc_entry(GNILND_PROC_SMSG, kgn_proc_root);
1422 remove_proc_entry(GNILND_PROC_STATS, kgn_proc_root);
1423 remove_proc_entry(GNILND_PROC_CKSUM_TEST, kgn_proc_root);
1424 remove_proc_entry(libcfs_lnd2modname(GNILND), NULL);