IB/hfi1: Add kernel receive context info to debugfs
authorKaike Wan <kaike.wan@intel.com>
Sun, 13 Aug 2017 15:09:04 +0000 (08:09 -0700)
committerDoug Ledford <dledford@redhat.com>
Tue, 22 Aug 2017 18:22:38 +0000 (14:22 -0400)
Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Kaike Wan <kaike.wan@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/hfi1/debugfs.c
drivers/infiniband/hw/hfi1/driver.c
drivers/infiniband/hw/hfi1/hfi.h

index 550119c6f1eed5241fd664e57e85c1990087faf6..c6a472f01025c9053088aae3239ba13048d496e0 100644 (file)
@@ -368,6 +368,52 @@ DEBUGFS_SEQ_FILE_OPS(sdes);
 DEBUGFS_SEQ_FILE_OPEN(sdes)
 DEBUGFS_FILE_OPS(sdes);
 
+static void *_rcds_seq_start(struct seq_file *s, loff_t *pos)
+{
+       struct hfi1_ibdev *ibd;
+       struct hfi1_devdata *dd;
+
+       ibd = (struct hfi1_ibdev *)s->private;
+       dd = dd_from_dev(ibd);
+       if (!dd->rcd || *pos >= dd->n_krcv_queues)
+               return NULL;
+       return pos;
+}
+
+static void *_rcds_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+       struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
+       struct hfi1_devdata *dd = dd_from_dev(ibd);
+
+       ++*pos;
+       if (!dd->rcd || *pos >= dd->n_krcv_queues)
+               return NULL;
+       return pos;
+}
+
+static void _rcds_seq_stop(struct seq_file *s, void *v)
+{
+}
+
+static int _rcds_seq_show(struct seq_file *s, void *v)
+{
+       struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
+       struct hfi1_devdata *dd = dd_from_dev(ibd);
+       struct hfi1_ctxtdata *rcd;
+       loff_t *spos = v;
+       loff_t i = *spos;
+
+       rcd = hfi1_rcd_get_by_index(dd, i);
+       if (rcd)
+               seqfile_dump_rcd(s, rcd);
+       hfi1_rcd_put(rcd);
+       return 0;
+}
+
+DEBUGFS_SEQ_FILE_OPS(rcds);
+DEBUGFS_SEQ_FILE_OPEN(rcds)
+DEBUGFS_FILE_OPS(rcds);
+
 /* read the per-device counters */
 static ssize_t dev_counters_read(struct file *file, char __user *buf,
                                 size_t count, loff_t *ppos)
@@ -1321,6 +1367,7 @@ void hfi1_dbg_ibdev_init(struct hfi1_ibdev *ibd)
        DEBUGFS_SEQ_FILE_CREATE(ctx_stats, ibd->hfi1_ibdev_dbg, ibd);
        DEBUGFS_SEQ_FILE_CREATE(qp_stats, ibd->hfi1_ibdev_dbg, ibd);
        DEBUGFS_SEQ_FILE_CREATE(sdes, ibd->hfi1_ibdev_dbg, ibd);
+       DEBUGFS_SEQ_FILE_CREATE(rcds, ibd->hfi1_ibdev_dbg, ibd);
        DEBUGFS_SEQ_FILE_CREATE(sdma_cpu_list, ibd->hfi1_ibdev_dbg, ibd);
        /* dev counter files */
        for (i = 0; i < ARRAY_SIZE(cntr_ops); i++)
index fc7085d6cf3fd576149aca31b05738915a23a084..7372cc00cb2d1f2cdd4414f03773b75f5b3f47ce 100644 (file)
@@ -1689,3 +1689,62 @@ int process_receive_invalid(struct hfi1_packet *packet)
                   rhf_rcv_type(packet->rhf));
        return RHF_RCV_CONTINUE;
 }
+
+void seqfile_dump_rcd(struct seq_file *s, struct hfi1_ctxtdata *rcd)
+{
+       struct hfi1_packet packet;
+       struct ps_mdata mdata;
+
+       seq_printf(s, "Rcd %u: RcvHdr cnt %u entsize %u %s head %llu tail %llu\n",
+                  rcd->ctxt, rcd->rcvhdrq_cnt, rcd->rcvhdrqentsize,
+                  HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL) ?
+                  "dma_rtail" : "nodma_rtail",
+                  read_uctxt_csr(rcd->dd, rcd->ctxt, RCV_HDR_HEAD) &
+                  RCV_HDR_HEAD_HEAD_MASK,
+                  read_uctxt_csr(rcd->dd, rcd->ctxt, RCV_HDR_TAIL));
+
+       init_packet(rcd, &packet);
+       init_ps_mdata(&mdata, &packet);
+
+       while (1) {
+               struct hfi1_devdata *dd = rcd->dd;
+               __le32 *rhf_addr = (__le32 *)rcd->rcvhdrq + mdata.ps_head +
+                                        dd->rhf_offset;
+               struct ib_header *hdr;
+               u64 rhf = rhf_to_cpu(rhf_addr);
+               u32 etype = rhf_rcv_type(rhf), qpn;
+               u8 opcode;
+               u32 psn;
+               u8 lnh;
+
+               if (ps_done(&mdata, rhf, rcd))
+                       break;
+
+               if (ps_skip(&mdata, rhf, rcd))
+                       goto next;
+
+               if (etype > RHF_RCV_TYPE_IB)
+                       goto next;
+
+               packet.hdr = hfi1_get_msgheader(dd, rhf_addr);
+               hdr = packet.hdr;
+
+               lnh = be16_to_cpu(hdr->lrh[0]) & 3;
+
+               if (lnh == HFI1_LRH_BTH)
+                       packet.ohdr = &hdr->u.oth;
+               else if (lnh == HFI1_LRH_GRH)
+                       packet.ohdr = &hdr->u.l.oth;
+               else
+                       goto next; /* just in case */
+
+               opcode = (be32_to_cpu(packet.ohdr->bth[0]) >> 24);
+               qpn = be32_to_cpu(packet.ohdr->bth[1]) & RVT_QPN_MASK;
+               psn = mask_psn(be32_to_cpu(packet.ohdr->bth[2]));
+
+               seq_printf(s, "\tEnt %u: opcode 0x%x, qpn 0x%x, psn 0x%x\n",
+                          mdata.ps_head, opcode, qpn, psn);
+next:
+               update_ps_mdata(&mdata, rcd);
+       }
+}
index b15749eab921f277673384e9642de35bf03b768c..eadb735d958c9d90b3fec4b69ecf5351ae74bc41 100644 (file)
@@ -1987,6 +1987,7 @@ int process_receive_error(struct hfi1_packet *packet);
 int kdeth_process_expected(struct hfi1_packet *packet);
 int kdeth_process_eager(struct hfi1_packet *packet);
 int process_receive_invalid(struct hfi1_packet *packet);
+void seqfile_dump_rcd(struct seq_file *s, struct hfi1_ctxtdata *rcd);
 
 /* global module parameter variables */
 extern unsigned int hfi1_max_mtu;