diff options
Diffstat (limited to 'net/rds/send.c')
| -rw-r--r-- | net/rds/send.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/net/rds/send.c b/net/rds/send.c index b2fccfc20769..9c1c6bcaa6c9 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | * | 31 | * |
| 32 | */ | 32 | */ |
| 33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
| 34 | #include <linux/gfp.h> | ||
| 34 | #include <net/sock.h> | 35 | #include <net/sock.h> |
| 35 | #include <linux/in.h> | 36 | #include <linux/in.h> |
| 36 | #include <linux/list.h> | 37 | #include <linux/list.h> |
| @@ -507,12 +508,13 @@ EXPORT_SYMBOL_GPL(rds_send_get_message); | |||
| 507 | */ | 508 | */ |
| 508 | void rds_send_remove_from_sock(struct list_head *messages, int status) | 509 | void rds_send_remove_from_sock(struct list_head *messages, int status) |
| 509 | { | 510 | { |
| 510 | unsigned long flags = 0; /* silence gcc :P */ | 511 | unsigned long flags; |
| 511 | struct rds_sock *rs = NULL; | 512 | struct rds_sock *rs = NULL; |
| 512 | struct rds_message *rm; | 513 | struct rds_message *rm; |
| 513 | 514 | ||
| 514 | local_irq_save(flags); | ||
| 515 | while (!list_empty(messages)) { | 515 | while (!list_empty(messages)) { |
| 516 | int was_on_sock = 0; | ||
| 517 | |||
| 516 | rm = list_entry(messages->next, struct rds_message, | 518 | rm = list_entry(messages->next, struct rds_message, |
| 517 | m_conn_item); | 519 | m_conn_item); |
| 518 | list_del_init(&rm->m_conn_item); | 520 | list_del_init(&rm->m_conn_item); |
| @@ -527,20 +529,19 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) | |||
| 527 | * while we're messing with it. It does not prevent the | 529 | * while we're messing with it. It does not prevent the |
| 528 | * message from being removed from the socket, though. | 530 | * message from being removed from the socket, though. |
| 529 | */ | 531 | */ |
| 530 | spin_lock(&rm->m_rs_lock); | 532 | spin_lock_irqsave(&rm->m_rs_lock, flags); |
| 531 | if (!test_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) | 533 | if (!test_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) |
| 532 | goto unlock_and_drop; | 534 | goto unlock_and_drop; |
| 533 | 535 | ||
| 534 | if (rs != rm->m_rs) { | 536 | if (rs != rm->m_rs) { |
| 535 | if (rs) { | 537 | if (rs) { |
| 536 | spin_unlock(&rs->rs_lock); | ||
| 537 | rds_wake_sk_sleep(rs); | 538 | rds_wake_sk_sleep(rs); |
| 538 | sock_put(rds_rs_to_sk(rs)); | 539 | sock_put(rds_rs_to_sk(rs)); |
| 539 | } | 540 | } |
| 540 | rs = rm->m_rs; | 541 | rs = rm->m_rs; |
| 541 | spin_lock(&rs->rs_lock); | ||
| 542 | sock_hold(rds_rs_to_sk(rs)); | 542 | sock_hold(rds_rs_to_sk(rs)); |
| 543 | } | 543 | } |
| 544 | spin_lock(&rs->rs_lock); | ||
| 544 | 545 | ||
| 545 | if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) { | 546 | if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) { |
| 546 | struct rds_rdma_op *ro = rm->m_rdma_op; | 547 | struct rds_rdma_op *ro = rm->m_rdma_op; |
| @@ -557,21 +558,22 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) | |||
| 557 | notifier->n_status = status; | 558 | notifier->n_status = status; |
| 558 | rm->m_rdma_op->r_notifier = NULL; | 559 | rm->m_rdma_op->r_notifier = NULL; |
| 559 | } | 560 | } |
| 560 | rds_message_put(rm); | 561 | was_on_sock = 1; |
| 561 | rm->m_rs = NULL; | 562 | rm->m_rs = NULL; |
| 562 | } | 563 | } |
| 564 | spin_unlock(&rs->rs_lock); | ||
| 563 | 565 | ||
| 564 | unlock_and_drop: | 566 | unlock_and_drop: |
| 565 | spin_unlock(&rm->m_rs_lock); | 567 | spin_unlock_irqrestore(&rm->m_rs_lock, flags); |
| 566 | rds_message_put(rm); | 568 | rds_message_put(rm); |
| 569 | if (was_on_sock) | ||
| 570 | rds_message_put(rm); | ||
| 567 | } | 571 | } |
| 568 | 572 | ||
| 569 | if (rs) { | 573 | if (rs) { |
| 570 | spin_unlock(&rs->rs_lock); | ||
| 571 | rds_wake_sk_sleep(rs); | 574 | rds_wake_sk_sleep(rs); |
| 572 | sock_put(rds_rs_to_sk(rs)); | 575 | sock_put(rds_rs_to_sk(rs)); |
| 573 | } | 576 | } |
| 574 | local_irq_restore(flags); | ||
| 575 | } | 577 | } |
| 576 | 578 | ||
| 577 | /* | 579 | /* |
| @@ -633,9 +635,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) | |||
| 633 | list_move(&rm->m_sock_item, &list); | 635 | list_move(&rm->m_sock_item, &list); |
| 634 | rds_send_sndbuf_remove(rs, rm); | 636 | rds_send_sndbuf_remove(rs, rm); |
| 635 | clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags); | 637 | clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags); |
| 636 | |||
| 637 | /* If this is a RDMA operation, notify the app. */ | ||
| 638 | __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED); | ||
| 639 | } | 638 | } |
| 640 | 639 | ||
| 641 | /* order flag updates with the rs lock */ | 640 | /* order flag updates with the rs lock */ |
| @@ -644,9 +643,6 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) | |||
| 644 | 643 | ||
| 645 | spin_unlock_irqrestore(&rs->rs_lock, flags); | 644 | spin_unlock_irqrestore(&rs->rs_lock, flags); |
| 646 | 645 | ||
| 647 | if (wake) | ||
| 648 | rds_wake_sk_sleep(rs); | ||
| 649 | |||
| 650 | conn = NULL; | 646 | conn = NULL; |
| 651 | 647 | ||
| 652 | /* now remove the messages from the conn list as needed */ | 648 | /* now remove the messages from the conn list as needed */ |
| @@ -654,6 +650,10 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) | |||
| 654 | /* We do this here rather than in the loop above, so that | 650 | /* We do this here rather than in the loop above, so that |
| 655 | * we don't have to nest m_rs_lock under rs->rs_lock */ | 651 | * we don't have to nest m_rs_lock under rs->rs_lock */ |
| 656 | spin_lock_irqsave(&rm->m_rs_lock, flags2); | 652 | spin_lock_irqsave(&rm->m_rs_lock, flags2); |
| 653 | /* If this is a RDMA operation, notify the app. */ | ||
| 654 | spin_lock(&rs->rs_lock); | ||
| 655 | __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED); | ||
| 656 | spin_unlock(&rs->rs_lock); | ||
| 657 | rm->m_rs = NULL; | 657 | rm->m_rs = NULL; |
| 658 | spin_unlock_irqrestore(&rm->m_rs_lock, flags2); | 658 | spin_unlock_irqrestore(&rm->m_rs_lock, flags2); |
| 659 | 659 | ||
| @@ -682,6 +682,9 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) | |||
| 682 | if (conn) | 682 | if (conn) |
| 683 | spin_unlock_irqrestore(&conn->c_lock, flags); | 683 | spin_unlock_irqrestore(&conn->c_lock, flags); |
| 684 | 684 | ||
| 685 | if (wake) | ||
| 686 | rds_wake_sk_sleep(rs); | ||
| 687 | |||
| 685 | while (!list_empty(&list)) { | 688 | while (!list_empty(&list)) { |
| 686 | rm = list_entry(list.next, struct rds_message, m_sock_item); | 689 | rm = list_entry(list.next, struct rds_message, m_sock_item); |
| 687 | list_del_init(&rm->m_sock_item); | 690 | list_del_init(&rm->m_sock_item); |
| @@ -815,7 +818,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 815 | int ret = 0; | 818 | int ret = 0; |
| 816 | int queued = 0, allocated_mr = 0; | 819 | int queued = 0, allocated_mr = 0; |
| 817 | int nonblock = msg->msg_flags & MSG_DONTWAIT; | 820 | int nonblock = msg->msg_flags & MSG_DONTWAIT; |
| 818 | long timeo = sock_rcvtimeo(sk, nonblock); | 821 | long timeo = sock_sndtimeo(sk, nonblock); |
| 819 | 822 | ||
| 820 | /* Mirror Linux UDP mirror of BSD error message compatibility */ | 823 | /* Mirror Linux UDP mirror of BSD error message compatibility */ |
| 821 | /* XXX: Perhaps MSG_MORE someday */ | 824 | /* XXX: Perhaps MSG_MORE someday */ |
| @@ -894,8 +897,10 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 894 | queue_delayed_work(rds_wq, &conn->c_conn_w, 0); | 897 | queue_delayed_work(rds_wq, &conn->c_conn_w, 0); |
| 895 | 898 | ||
| 896 | ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); | 899 | ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); |
| 897 | if (ret) | 900 | if (ret) { |
| 901 | rs->rs_seen_congestion = 1; | ||
| 898 | goto out; | 902 | goto out; |
| 903 | } | ||
| 899 | 904 | ||
| 900 | while (!rds_send_queue_rm(rs, conn, rm, rs->rs_bound_port, | 905 | while (!rds_send_queue_rm(rs, conn, rm, rs->rs_bound_port, |
| 901 | dport, &queued)) { | 906 | dport, &queued)) { |
| @@ -910,7 +915,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
| 910 | goto out; | 915 | goto out; |
| 911 | } | 916 | } |
| 912 | 917 | ||
| 913 | timeo = wait_event_interruptible_timeout(*sk->sk_sleep, | 918 | timeo = wait_event_interruptible_timeout(*sk_sleep(sk), |
| 914 | rds_send_queue_rm(rs, conn, rm, | 919 | rds_send_queue_rm(rs, conn, rm, |
| 915 | rs->rs_bound_port, | 920 | rs->rs_bound_port, |
| 916 | dport, | 921 | dport, |
