aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorMike Marciniszyn <mike.marciniszyn@intel.com>2013-06-15 17:07:14 -0400
committerRoland Dreier <roland@purestorage.com>2013-06-21 20:19:52 -0400
commit1dd173b01f52c7a197cab20563d5f4967472a852 (patch)
treefa7194bc8024ff795bc38ec692e36dd2d5d279b6 /drivers/infiniband
parent17db3a92c144a0f8a81c52e94b7110bc86b5067f (diff)
IB/qib: Add qp_stats debug file
This adds a seq_file iterator for reporting the QP hash table when the qp_stats file is read. Reviewed-by: Dean Luick <dean.luick@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/qib/qib_debugfs.c54
-rw-r--r--drivers/infiniband/hw/qib/qib_qp.c94
-rw-r--r--drivers/infiniband/hw/qib/qib_verbs.h14
3 files changed, 161 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/qib/qib_debugfs.c b/drivers/infiniband/hw/qib/qib_debugfs.c
index a4e6ee154f19..799a0c3bffc4 100644
--- a/drivers/infiniband/hw/qib/qib_debugfs.c
+++ b/drivers/infiniband/hw/qib/qib_debugfs.c
@@ -188,6 +188,59 @@ static int _ctx_stats_seq_show(struct seq_file *s, void *v)
188 188
189DEBUGFS_FILE(ctx_stats) 189DEBUGFS_FILE(ctx_stats)
190 190
191static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos)
192{
193 struct qib_qp_iter *iter;
194 loff_t n = *pos;
195
196 iter = qib_qp_iter_init(s->private);
197 if (!iter)
198 return NULL;
199
200 while (n--) {
201 if (qib_qp_iter_next(iter)) {
202 kfree(iter);
203 return NULL;
204 }
205 }
206
207 return iter;
208}
209
210static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr,
211 loff_t *pos)
212{
213 struct qib_qp_iter *iter = iter_ptr;
214
215 (*pos)++;
216
217 if (qib_qp_iter_next(iter)) {
218 kfree(iter);
219 return NULL;
220 }
221
222 return iter;
223}
224
225static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr)
226{
227 /* nothing for now */
228}
229
230static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr)
231{
232 struct qib_qp_iter *iter = iter_ptr;
233
234 if (!iter)
235 return 0;
236
237 qib_qp_iter_print(s, iter);
238
239 return 0;
240}
241
242DEBUGFS_FILE(qp_stats)
243
191void qib_dbg_ibdev_init(struct qib_ibdev *ibd) 244void qib_dbg_ibdev_init(struct qib_ibdev *ibd)
192{ 245{
193 char name[10]; 246 char name[10];
@@ -200,6 +253,7 @@ void qib_dbg_ibdev_init(struct qib_ibdev *ibd)
200 } 253 }
201 DEBUGFS_FILE_CREATE(opcode_stats); 254 DEBUGFS_FILE_CREATE(opcode_stats);
202 DEBUGFS_FILE_CREATE(ctx_stats); 255 DEBUGFS_FILE_CREATE(ctx_stats);
256 DEBUGFS_FILE_CREATE(qp_stats);
203 return; 257 return;
204} 258}
205 259
diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c
index c1f573a331c7..3cca55b51e54 100644
--- a/drivers/infiniband/hw/qib/qib_qp.c
+++ b/drivers/infiniband/hw/qib/qib_qp.c
@@ -35,6 +35,9 @@
35#include <linux/err.h> 35#include <linux/err.h>
36#include <linux/vmalloc.h> 36#include <linux/vmalloc.h>
37#include <linux/jhash.h> 37#include <linux/jhash.h>
38#ifdef CONFIG_DEBUG_FS
39#include <linux/seq_file.h>
40#endif
38 41
39#include "qib.h" 42#include "qib.h"
40 43
@@ -1287,3 +1290,94 @@ void qib_get_credit(struct qib_qp *qp, u32 aeth)
1287 } 1290 }
1288 } 1291 }
1289} 1292}
1293
1294#ifdef CONFIG_DEBUG_FS
1295
1296struct qib_qp_iter {
1297 struct qib_ibdev *dev;
1298 struct qib_qp *qp;
1299 int n;
1300};
1301
1302struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev)
1303{
1304 struct qib_qp_iter *iter;
1305
1306 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
1307 if (!iter)
1308 return NULL;
1309
1310 iter->dev = dev;
1311 if (qib_qp_iter_next(iter)) {
1312 kfree(iter);
1313 return NULL;
1314 }
1315
1316 return iter;
1317}
1318
1319int qib_qp_iter_next(struct qib_qp_iter *iter)
1320{
1321 struct qib_ibdev *dev = iter->dev;
1322 int n = iter->n;
1323 int ret = 1;
1324 struct qib_qp *pqp = iter->qp;
1325 struct qib_qp *qp;
1326
1327 rcu_read_lock();
1328 for (; n < dev->qp_table_size; n++) {
1329 if (pqp)
1330 qp = rcu_dereference(pqp->next);
1331 else
1332 qp = rcu_dereference(dev->qp_table[n]);
1333 pqp = qp;
1334 if (qp) {
1335 if (iter->qp)
1336 atomic_dec(&iter->qp->refcount);
1337 atomic_inc(&qp->refcount);
1338 rcu_read_unlock();
1339 iter->qp = qp;
1340 iter->n = n;
1341 return 0;
1342 }
1343 }
1344 rcu_read_unlock();
1345 if (iter->qp)
1346 atomic_dec(&iter->qp->refcount);
1347 return ret;
1348}
1349
1350static const char * const qp_type_str[] = {
1351 "SMI", "GSI", "RC", "UC", "UD",
1352};
1353
1354void qib_qp_iter_print(struct seq_file *s, struct qib_qp_iter *iter)
1355{
1356 struct qib_swqe *wqe;
1357 struct qib_qp *qp = iter->qp;
1358
1359 wqe = get_swqe_ptr(qp, qp->s_last);
1360 seq_printf(s,
1361 "N %d QP%u %s %u %u %u f=%x %u %u %u %u %u PSN %x %x %x %x %x (%u %u %u %u %u %u) QP%u LID %x\n",
1362 iter->n,
1363 qp->ibqp.qp_num,
1364 qp_type_str[qp->ibqp.qp_type],
1365 qp->state,
1366 wqe->wr.opcode,
1367 qp->s_hdrwords,
1368 qp->s_flags,
1369 atomic_read(&qp->s_dma_busy),
1370 !list_empty(&qp->iowait),
1371 qp->timeout,
1372 wqe->ssn,
1373 qp->s_lsn,
1374 qp->s_last_psn,
1375 qp->s_psn, qp->s_next_psn,
1376 qp->s_sending_psn, qp->s_sending_hpsn,
1377 qp->s_last, qp->s_acked, qp->s_cur,
1378 qp->s_tail, qp->s_head, qp->s_size,
1379 qp->remote_qpn,
1380 qp->remote_ah_attr.dlid);
1381}
1382
1383#endif
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h
index 4a22a85b9f03..012e2c7575ad 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.h
+++ b/drivers/infiniband/hw/qib/qib_verbs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012 Intel Corporation. All rights reserved. 2 * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved.
3 * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. 3 * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
4 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. 4 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
5 * 5 *
@@ -917,6 +917,18 @@ void qib_init_qpn_table(struct qib_devdata *dd, struct qib_qpn_table *qpt);
917 917
918void qib_free_qpn_table(struct qib_qpn_table *qpt); 918void qib_free_qpn_table(struct qib_qpn_table *qpt);
919 919
920#ifdef CONFIG_DEBUG_FS
921
922struct qib_qp_iter;
923
924struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev);
925
926int qib_qp_iter_next(struct qib_qp_iter *iter);
927
928void qib_qp_iter_print(struct seq_file *s, struct qib_qp_iter *iter);
929
930#endif
931
920void qib_get_credit(struct qib_qp *qp, u32 aeth); 932void qib_get_credit(struct qib_qp *qp, u32 aeth);
921 933
922unsigned qib_pkt_delay(u32 plen, u8 snd_mult, u8 rcv_mult); 934unsigned qib_pkt_delay(u32 plen, u8 snd_mult, u8 rcv_mult);