diff options
-rw-r--r-- | net/sctp/socket.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 981aaf8b6ace..5f83a6a2fa67 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -6593,6 +6593,40 @@ static void __sctp_write_space(struct sctp_association *asoc) | |||
6593 | } | 6593 | } |
6594 | } | 6594 | } |
6595 | 6595 | ||
6596 | static void sctp_wake_up_waiters(struct sock *sk, | ||
6597 | struct sctp_association *asoc) | ||
6598 | { | ||
6599 | struct sctp_association *tmp = asoc; | ||
6600 | |||
6601 | /* We do accounting for the sndbuf space per association, | ||
6602 | * so we only need to wake our own association. | ||
6603 | */ | ||
6604 | if (asoc->ep->sndbuf_policy) | ||
6605 | return __sctp_write_space(asoc); | ||
6606 | |||
6607 | /* Accounting for the sndbuf space is per socket, so we | ||
6608 | * need to wake up others, try to be fair and in case of | ||
6609 | * other associations, let them have a go first instead | ||
6610 | * of just doing a sctp_write_space() call. | ||
6611 | * | ||
6612 | * Note that we reach sctp_wake_up_waiters() only when | ||
6613 | * associations free up queued chunks, thus we are under | ||
6614 | * lock and the list of associations on a socket is | ||
6615 | * guaranteed not to change. | ||
6616 | */ | ||
6617 | for (tmp = list_next_entry(tmp, asocs); 1; | ||
6618 | tmp = list_next_entry(tmp, asocs)) { | ||
6619 | /* Manually skip the head element. */ | ||
6620 | if (&tmp->asocs == &((sctp_sk(sk))->ep->asocs)) | ||
6621 | continue; | ||
6622 | /* Wake up association. */ | ||
6623 | __sctp_write_space(tmp); | ||
6624 | /* We've reached the end. */ | ||
6625 | if (tmp == asoc) | ||
6626 | break; | ||
6627 | } | ||
6628 | } | ||
6629 | |||
6596 | /* Do accounting for the sndbuf space. | 6630 | /* Do accounting for the sndbuf space. |
6597 | * Decrement the used sndbuf space of the corresponding association by the | 6631 | * Decrement the used sndbuf space of the corresponding association by the |
6598 | * data size which was just transmitted(freed). | 6632 | * data size which was just transmitted(freed). |
@@ -6620,7 +6654,7 @@ static void sctp_wfree(struct sk_buff *skb) | |||
6620 | sk_mem_uncharge(sk, skb->truesize); | 6654 | sk_mem_uncharge(sk, skb->truesize); |
6621 | 6655 | ||
6622 | sock_wfree(skb); | 6656 | sock_wfree(skb); |
6623 | __sctp_write_space(asoc); | 6657 | sctp_wake_up_waiters(sk, asoc); |
6624 | 6658 | ||
6625 | sctp_association_put(asoc); | 6659 | sctp_association_put(asoc); |
6626 | } | 6660 | } |