aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/ib_cm.c
diff options
context:
space:
mode:
authorZach Brown <zach.brown@oracle.com>2010-07-14 16:55:35 -0400
committerAndy Grover <andy.grover@oracle.com>2010-09-08 21:16:40 -0400
commitf046011cd73c372267befd10242988eb744649fe (patch)
treed184275400dee81f2a5027728bda849bec338d99 /net/rds/ib_cm.c
parentef87b7ea39a91906218a262686bcb8bad8b6b46e (diff)
RDS/IB: track signaled sends
We're seeing bugs today where IB connection shutdown clears the send ring while the tasklet is processing completed sends. Implementation details cause this to dereference a null pointer. Shutdown needs to wait for send completion to stop before tearing down the connection. We can't simply wait for the ring to empty because it may contain unsignaled sends that will never be processed. This patch tracks the number of signaled sends that we've posted and waits for them to complete. It also makes sure that the tasklet has finished executing. Signed-off-by: Zach Brown <zach.brown@oracle.com>
Diffstat (limited to 'net/rds/ib_cm.c')
-rw-r--r--net/rds/ib_cm.c14
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