aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/send.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds/send.c')
-rw-r--r--net/rds/send.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/rds/send.c b/net/rds/send.c
index 51e2def50b12..4629a0b63bbd 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -507,12 +507,13 @@ EXPORT_SYMBOL_GPL(rds_send_get_message);
507 */ 507 */
508void rds_send_remove_from_sock(struct list_head *messages, int status) 508void rds_send_remove_from_sock(struct list_head *messages, int status)
509{ 509{
510 unsigned long flags = 0; /* silence gcc :P */ 510 unsigned long flags;
511 struct rds_sock *rs = NULL; 511 struct rds_sock *rs = NULL;
512 struct rds_message *rm; 512 struct rds_message *rm;
513 513
514 local_irq_save(flags);
515 while (!list_empty(messages)) { 514 while (!list_empty(messages)) {
515 int was_on_sock = 0;
516
516 rm = list_entry(messages->next, struct rds_message, 517 rm = list_entry(messages->next, struct rds_message,
517 m_conn_item); 518 m_conn_item);
518 list_del_init(&rm->m_conn_item); 519 list_del_init(&rm->m_conn_item);
@@ -527,7 +528,7 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
527 * while we're messing with it. It does not prevent the 528 * while we're messing with it. It does not prevent the
528 * message from being removed from the socket, though. 529 * message from being removed from the socket, though.
529 */ 530 */
530 spin_lock(&rm->m_rs_lock); 531 spin_lock_irqsave(&rm->m_rs_lock, flags);
531 if (!test_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) 532 if (!test_bit(RDS_MSG_ON_SOCK, &rm->m_flags))
532 goto unlock_and_drop; 533 goto unlock_and_drop;
533 534
@@ -556,21 +557,22 @@ void rds_send_remove_from_sock(struct list_head *messages, int status)
556 notifier->n_status = status; 557 notifier->n_status = status;
557 rm->m_rdma_op->r_notifier = NULL; 558 rm->m_rdma_op->r_notifier = NULL;
558 } 559 }
559 rds_message_put(rm); 560 was_on_sock = 1;
560 rm->m_rs = NULL; 561 rm->m_rs = NULL;
561 } 562 }
562 spin_unlock(&rs->rs_lock); 563 spin_unlock(&rs->rs_lock);
563 564
564unlock_and_drop: 565unlock_and_drop:
565 spin_unlock(&rm->m_rs_lock); 566 spin_unlock_irqrestore(&rm->m_rs_lock, flags);
566 rds_message_put(rm); 567 rds_message_put(rm);
568 if (was_on_sock)
569 rds_message_put(rm);
567 } 570 }
568 571
569 if (rs) { 572 if (rs) {
570 rds_wake_sk_sleep(rs); 573 rds_wake_sk_sleep(rs);
571 sock_put(rds_rs_to_sk(rs)); 574 sock_put(rds_rs_to_sk(rs));
572 } 575 }
573 local_irq_restore(flags);
574} 576}
575 577
576/* 578/*