diff options
Diffstat (limited to 'net/rds/send.c')
-rw-r--r-- | net/rds/send.c | 14 |
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 | */ |
508 | void rds_send_remove_from_sock(struct list_head *messages, int status) | 508 | void 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 | ||
564 | unlock_and_drop: | 565 | unlock_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 | /* |