diff options
author | Vipul Pandya <vipul@chelsio.com> | 2012-12-10 04:30:56 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-12-20 02:03:12 -0500 |
commit | 793dad94e7455c113e391bd3d418c7b95a4c2687 (patch) | |
tree | c5352be56d70a9ac46b81da71fb6c8c0e06a2566 /drivers/infiniband/hw/cxgb4/device.c | |
parent | 1cab775c3e75f1250c965feafd061d696df36e53 (diff) |
RDMA/cxgb4: Fix bug for active and passive LE hash collision path
Retries active opens for INUSE errors.
Logs any active ofld_connect_wr error replies.
Sends ofld_connect_wr on same ctrlq. It needs to go on the same control txq as
regular CPL active/passive messages.
Retries on active open replies with EADDRINUSE.
Uses active open fw wr only if active filter region is set.
Adds stat for ofld_connect_wr failures.
This patch also adds debugfs file to show endpoints.
Signed-off-by: Vipul Pandya <vipul@chelsio.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/cxgb4/device.c')
-rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 6b5b3d15e48d..ba11c76c0b5a 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
@@ -280,6 +280,10 @@ static int stats_show(struct seq_file *seq, void *v) | |||
280 | db_state_str[dev->db_state], | 280 | db_state_str[dev->db_state], |
281 | dev->rdev.stats.db_state_transitions); | 281 | dev->rdev.stats.db_state_transitions); |
282 | seq_printf(seq, "TCAM_FULL: %10llu\n", dev->rdev.stats.tcam_full); | 282 | seq_printf(seq, "TCAM_FULL: %10llu\n", dev->rdev.stats.tcam_full); |
283 | seq_printf(seq, "ACT_OFLD_CONN_FAILS: %10llu\n", | ||
284 | dev->rdev.stats.act_ofld_conn_fails); | ||
285 | seq_printf(seq, "PAS_OFLD_CONN_FAILS: %10llu\n", | ||
286 | dev->rdev.stats.pas_ofld_conn_fails); | ||
283 | return 0; | 287 | return 0; |
284 | } | 288 | } |
285 | 289 | ||
@@ -310,6 +314,9 @@ static ssize_t stats_clear(struct file *file, const char __user *buf, | |||
310 | dev->rdev.stats.db_empty = 0; | 314 | dev->rdev.stats.db_empty = 0; |
311 | dev->rdev.stats.db_drop = 0; | 315 | dev->rdev.stats.db_drop = 0; |
312 | dev->rdev.stats.db_state_transitions = 0; | 316 | dev->rdev.stats.db_state_transitions = 0; |
317 | dev->rdev.stats.tcam_full = 0; | ||
318 | dev->rdev.stats.act_ofld_conn_fails = 0; | ||
319 | dev->rdev.stats.pas_ofld_conn_fails = 0; | ||
313 | mutex_unlock(&dev->rdev.stats.lock); | 320 | mutex_unlock(&dev->rdev.stats.lock); |
314 | return count; | 321 | return count; |
315 | } | 322 | } |
@@ -323,6 +330,113 @@ static const struct file_operations stats_debugfs_fops = { | |||
323 | .write = stats_clear, | 330 | .write = stats_clear, |
324 | }; | 331 | }; |
325 | 332 | ||
333 | static int dump_ep(int id, void *p, void *data) | ||
334 | { | ||
335 | struct c4iw_ep *ep = p; | ||
336 | struct c4iw_debugfs_data *epd = data; | ||
337 | int space; | ||
338 | int cc; | ||
339 | |||
340 | space = epd->bufsize - epd->pos - 1; | ||
341 | if (space == 0) | ||
342 | return 1; | ||
343 | |||
344 | cc = snprintf(epd->buf + epd->pos, space, | ||
345 | "ep %p cm_id %p qp %p state %d flags 0x%lx history 0x%lx " | ||
346 | "hwtid %d atid %d %pI4:%d <-> %pI4:%d\n", | ||
347 | ep, ep->com.cm_id, ep->com.qp, (int)ep->com.state, | ||
348 | ep->com.flags, ep->com.history, ep->hwtid, ep->atid, | ||
349 | &ep->com.local_addr.sin_addr.s_addr, | ||
350 | ntohs(ep->com.local_addr.sin_port), | ||
351 | &ep->com.remote_addr.sin_addr.s_addr, | ||
352 | ntohs(ep->com.remote_addr.sin_port)); | ||
353 | if (cc < space) | ||
354 | epd->pos += cc; | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int dump_listen_ep(int id, void *p, void *data) | ||
359 | { | ||
360 | struct c4iw_listen_ep *ep = p; | ||
361 | struct c4iw_debugfs_data *epd = data; | ||
362 | int space; | ||
363 | int cc; | ||
364 | |||
365 | space = epd->bufsize - epd->pos - 1; | ||
366 | if (space == 0) | ||
367 | return 1; | ||
368 | |||
369 | cc = snprintf(epd->buf + epd->pos, space, | ||
370 | "ep %p cm_id %p state %d flags 0x%lx stid %d backlog %d " | ||
371 | "%pI4:%d\n", ep, ep->com.cm_id, (int)ep->com.state, | ||
372 | ep->com.flags, ep->stid, ep->backlog, | ||
373 | &ep->com.local_addr.sin_addr.s_addr, | ||
374 | ntohs(ep->com.local_addr.sin_port)); | ||
375 | if (cc < space) | ||
376 | epd->pos += cc; | ||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static int ep_release(struct inode *inode, struct file *file) | ||
381 | { | ||
382 | struct c4iw_debugfs_data *epd = file->private_data; | ||
383 | if (!epd) { | ||
384 | pr_info("%s null qpd?\n", __func__); | ||
385 | return 0; | ||
386 | } | ||
387 | vfree(epd->buf); | ||
388 | kfree(epd); | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int ep_open(struct inode *inode, struct file *file) | ||
393 | { | ||
394 | struct c4iw_debugfs_data *epd; | ||
395 | int ret = 0; | ||
396 | int count = 1; | ||
397 | |||
398 | epd = kmalloc(sizeof(*epd), GFP_KERNEL); | ||
399 | if (!epd) { | ||
400 | ret = -ENOMEM; | ||
401 | goto out; | ||
402 | } | ||
403 | epd->devp = inode->i_private; | ||
404 | epd->pos = 0; | ||
405 | |||
406 | spin_lock_irq(&epd->devp->lock); | ||
407 | idr_for_each(&epd->devp->hwtid_idr, count_idrs, &count); | ||
408 | idr_for_each(&epd->devp->atid_idr, count_idrs, &count); | ||
409 | idr_for_each(&epd->devp->stid_idr, count_idrs, &count); | ||
410 | spin_unlock_irq(&epd->devp->lock); | ||
411 | |||
412 | epd->bufsize = count * 160; | ||
413 | epd->buf = vmalloc(epd->bufsize); | ||
414 | if (!epd->buf) { | ||
415 | ret = -ENOMEM; | ||
416 | goto err1; | ||
417 | } | ||
418 | |||
419 | spin_lock_irq(&epd->devp->lock); | ||
420 | idr_for_each(&epd->devp->hwtid_idr, dump_ep, epd); | ||
421 | idr_for_each(&epd->devp->atid_idr, dump_ep, epd); | ||
422 | idr_for_each(&epd->devp->stid_idr, dump_listen_ep, epd); | ||
423 | spin_unlock_irq(&epd->devp->lock); | ||
424 | |||
425 | file->private_data = epd; | ||
426 | goto out; | ||
427 | err1: | ||
428 | kfree(epd); | ||
429 | out: | ||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | static const struct file_operations ep_debugfs_fops = { | ||
434 | .owner = THIS_MODULE, | ||
435 | .open = ep_open, | ||
436 | .release = ep_release, | ||
437 | .read = debugfs_read, | ||
438 | }; | ||
439 | |||
326 | static int setup_debugfs(struct c4iw_dev *devp) | 440 | static int setup_debugfs(struct c4iw_dev *devp) |
327 | { | 441 | { |
328 | struct dentry *de; | 442 | struct dentry *de; |
@@ -345,6 +459,11 @@ static int setup_debugfs(struct c4iw_dev *devp) | |||
345 | if (de && de->d_inode) | 459 | if (de && de->d_inode) |
346 | de->d_inode->i_size = 4096; | 460 | de->d_inode->i_size = 4096; |
347 | 461 | ||
462 | de = debugfs_create_file("eps", S_IWUSR, devp->debugfs_root, | ||
463 | (void *)devp, &ep_debugfs_fops); | ||
464 | if (de && de->d_inode) | ||
465 | de->d_inode->i_size = 4096; | ||
466 | |||
348 | return 0; | 467 | return 0; |
349 | } | 468 | } |
350 | 469 | ||
@@ -476,6 +595,9 @@ static void c4iw_dealloc(struct uld_ctx *ctx) | |||
476 | idr_destroy(&ctx->dev->cqidr); | 595 | idr_destroy(&ctx->dev->cqidr); |
477 | idr_destroy(&ctx->dev->qpidr); | 596 | idr_destroy(&ctx->dev->qpidr); |
478 | idr_destroy(&ctx->dev->mmidr); | 597 | idr_destroy(&ctx->dev->mmidr); |
598 | idr_destroy(&ctx->dev->hwtid_idr); | ||
599 | idr_destroy(&ctx->dev->stid_idr); | ||
600 | idr_destroy(&ctx->dev->atid_idr); | ||
479 | iounmap(ctx->dev->rdev.oc_mw_kva); | 601 | iounmap(ctx->dev->rdev.oc_mw_kva); |
480 | ib_dealloc_device(&ctx->dev->ibdev); | 602 | ib_dealloc_device(&ctx->dev->ibdev); |
481 | ctx->dev = NULL; | 603 | ctx->dev = NULL; |
@@ -533,6 +655,9 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | |||
533 | idr_init(&devp->cqidr); | 655 | idr_init(&devp->cqidr); |
534 | idr_init(&devp->qpidr); | 656 | idr_init(&devp->qpidr); |
535 | idr_init(&devp->mmidr); | 657 | idr_init(&devp->mmidr); |
658 | idr_init(&devp->hwtid_idr); | ||
659 | idr_init(&devp->stid_idr); | ||
660 | idr_init(&devp->atid_idr); | ||
536 | spin_lock_init(&devp->lock); | 661 | spin_lock_init(&devp->lock); |
537 | mutex_init(&devp->rdev.stats.lock); | 662 | mutex_init(&devp->rdev.stats.lock); |
538 | mutex_init(&devp->db_mutex); | 663 | mutex_init(&devp->db_mutex); |