aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sctp/socket.c36
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
6596static 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}