diff options
Diffstat (limited to 'net/rds/ib_cm.c')
-rw-r--r-- | net/rds/ib_cm.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 10f6a8815cd0..123c7d33b54e 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c | |||
@@ -615,11 +615,18 @@ void rds_ib_conn_shutdown(struct rds_connection *conn) | |||
615 | } | 615 | } |
616 | 616 | ||
617 | /* | 617 | /* |
618 | * Don't wait for the send ring to be empty -- there may be completed | 618 | * We want to wait for tx and rx completion to finish |
619 | * non-signaled entries sitting on there. We unmap these below. | 619 | * before we tear down the connection, but we have to be |
620 | * careful not to get stuck waiting on a send ring that | ||
621 | * only has unsignaled sends in it. We've shutdown new | ||
622 | * sends before getting here so by waiting for signaled | ||
623 | * sends to complete we're ensured that there will be no | ||
624 | * more tx processing. | ||
620 | */ | 625 | */ |
621 | wait_event(rds_ib_ring_empty_wait, | 626 | wait_event(rds_ib_ring_empty_wait, |
622 | rds_ib_ring_empty(&ic->i_recv_ring)); | 627 | rds_ib_ring_empty(&ic->i_recv_ring) && |
628 | (atomic_read(&ic->i_signaled_sends) == 0)); | ||
629 | tasklet_kill(&ic->i_recv_tasklet); | ||
623 | 630 | ||
624 | if (ic->i_send_hdrs) | 631 | if (ic->i_send_hdrs) |
625 | ib_dma_free_coherent(dev, | 632 | ib_dma_free_coherent(dev, |
@@ -729,6 +736,7 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp) | |||
729 | #ifndef KERNEL_HAS_ATOMIC64 | 736 | #ifndef KERNEL_HAS_ATOMIC64 |
730 | spin_lock_init(&ic->i_ack_lock); | 737 | spin_lock_init(&ic->i_ack_lock); |
731 | #endif | 738 | #endif |
739 | atomic_set(&ic->i_signaled_sends, 0); | ||
732 | 740 | ||
733 | /* | 741 | /* |
734 | * rds_ib_conn_shutdown() waits for these to be emptied so they | 742 | * rds_ib_conn_shutdown() waits for these to be emptied so they |