aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
authorTina Yang <Tina.Yang@oracle.com>2010-03-11 08:50:00 -0500
committerDavid S. Miller <davem@davemloft.net>2010-03-17 00:16:55 -0400
commit048c15e641289d902f7ef9f1241068d8045e210c (patch)
treef4e7f27a411b9310c98c41e82285e211abcbfbd7 /net/rds
parent2e7b3b994529d4760231a45a6b88950187bda877 (diff)
RDS: Fix send locking issue
Fix a deadlock between rds_rdma_send_complete() and rds_send_remove_from_sock() when rds socket lock and rds message lock are acquired out-of-order. Signed-off-by: Tina Yang <Tina.Yang@oracle.com> Signed-off-by: Andy Grover <andy.grover@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/send.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/net/rds/send.c b/net/rds/send.c
index ad2e46947c8a..1a2ef24fbc94 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -533,14 +533,13 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
533 533
534 if (rs != rm->m_rs) { 534 if (rs != rm->m_rs) {
535 if (rs) { 535 if (rs) {
536 spin_unlock(&rs->rs_lock);
537 rds_wake_sk_sleep(rs); 536 rds_wake_sk_sleep(rs);
538 sock_put(rds_rs_to_sk(rs)); 537 sock_put(rds_rs_to_sk(rs));
539 } 538 }
540 rs = rm->m_rs; 539 rs = rm->m_rs;
541 spin_lock(&rs->rs_lock);
542 sock_hold(rds_rs_to_sk(rs)); 540 sock_hold(rds_rs_to_sk(rs));
543 } 541 }
542 spin_lock(&rs->rs_lock);
544 543
545 if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) { 544 if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) {
546 struct rds_rdma_op *ro = rm->m_rdma_op; 545 struct rds_rdma_op *ro = rm->m_rdma_op;
@@ -560,6 +559,7 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
560 rds_message_put(rm); 559 rds_message_put(rm);
561 rm->m_rs = NULL; 560 rm->m_rs = NULL;
562 } 561 }
562 spin_unlock(&rs->rs_lock);
563 563
564unlock_and_drop: 564unlock_and_drop:
565 spin_unlock(&rm->m_rs_lock); 565 spin_unlock(&rm->m_rs_lock);
@@ -567,7 +567,6 @@ unlock_and_drop:
567 } 567 }
568 568
569 if (rs) { 569 if (rs) {
570 spin_unlock(&rs->rs_lock);
571 rds_wake_sk_sleep(rs); 570 rds_wake_sk_sleep(rs);
572 sock_put(rds_rs_to_sk(rs)); 571 sock_put(rds_rs_to_sk(rs));
573 } 572 }