aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/send.c
diff options
context:
space:
mode:
authorAndy Grover <andy.grover@oracle.com>2010-03-29 19:50:54 -0400
committerAndy Grover <andy.grover@oracle.com>2010-09-08 21:07:32 -0400
commit9de0864cf55927a7383b5ba6e48834ff3ef053de (patch)
tree875dcd8ecf01f539ac050763b449573d4210dadf /net/rds/send.c
parent7c82eaf00ec7d460932be9314b29997006b799b6 (diff)
RDS: Fix locking in send on m_rs_lock
Do not nest m_rs_lock under c_lock Disable interrupts in {rdma,atomic}_send_complete Signed-off-by: Andy Grover <andy.grover@oracle.com>
Diffstat (limited to 'net/rds/send.c')
-rw-r--r--net/rds/send.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/net/rds/send.c b/net/rds/send.c
index aee58f931b69..725fb0419797 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -415,8 +415,9 @@ void rds_rdma_send_complete(struct rds_message *rm, int status)
415 struct rds_sock *rs = NULL; 415 struct rds_sock *rs = NULL;
416 struct rds_rdma_op *ro; 416 struct rds_rdma_op *ro;
417 struct rds_notifier *notifier; 417 struct rds_notifier *notifier;
418 unsigned long flags;
418 419
419 spin_lock(&rm->m_rs_lock); 420 spin_lock_irqsave(&rm->m_rs_lock, flags);
420 421
421 ro = rm->m_rdma_op; 422 ro = rm->m_rdma_op;
422 if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) && 423 if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) &&
@@ -433,7 +434,7 @@ void rds_rdma_send_complete(struct rds_message *rm, int status)
433 ro->r_notifier = NULL; 434 ro->r_notifier = NULL;
434 } 435 }
435 436
436 spin_unlock(&rm->m_rs_lock); 437 spin_unlock_irqrestore(&rm->m_rs_lock, flags);
437 438
438 if (rs) { 439 if (rs) {
439 rds_wake_sk_sleep(rs); 440 rds_wake_sk_sleep(rs);
@@ -647,8 +648,8 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
647 list_for_each_entry(rm, &list, m_sock_item) { 648 list_for_each_entry(rm, &list, m_sock_item) {
648 649
649 conn = rm->m_inc.i_conn; 650 conn = rm->m_inc.i_conn;
650 spin_lock_irqsave(&conn->c_lock, flags);
651 651
652 spin_lock_irqsave(&conn->c_lock, flags);
652 /* 653 /*
653 * Maybe someone else beat us to removing rm from the conn. 654 * Maybe someone else beat us to removing rm from the conn.
654 * If we race with their flag update we'll get the lock and 655 * If we race with their flag update we'll get the lock and
@@ -658,23 +659,23 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
658 spin_unlock_irqrestore(&conn->c_lock, flags); 659 spin_unlock_irqrestore(&conn->c_lock, flags);
659 continue; 660 continue;
660 } 661 }
662 list_del_init(&rm->m_conn_item);
663 spin_unlock_irqrestore(&conn->c_lock, flags);
661 664
662 /* 665 /*
663 * Couldn't grab m_rs_lock in top loop (lock ordering), 666 * Couldn't grab m_rs_lock in top loop (lock ordering),
664 * but we can now. 667 * but we can now.
665 */ 668 */
666 spin_lock(&rm->m_rs_lock); 669 spin_lock_irqsave(&rm->m_rs_lock, flags);
667 670
668 spin_lock(&rs->rs_lock); 671 spin_lock(&rs->rs_lock);
669 __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED); 672 __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED);
670 spin_unlock(&rs->rs_lock); 673 spin_unlock(&rs->rs_lock);
671 674
672 rm->m_rs = NULL; 675 rm->m_rs = NULL;
673 spin_unlock(&rm->m_rs_lock); 676 spin_unlock_irqrestore(&rm->m_rs_lock, flags);
674 677
675 list_del_init(&rm->m_conn_item);
676 rds_message_put(rm); 678 rds_message_put(rm);
677 spin_unlock_irqrestore(&conn->c_lock, flags);
678 } 679 }
679 680
680 rds_wake_sk_sleep(rs); 681 rds_wake_sk_sleep(rs);