diff options
Diffstat (limited to 'net/sctp/transport.c')
-rw-r--r-- | net/sctp/transport.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 206cf5238fd3..4e45bb68aef0 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -163,13 +163,11 @@ void sctp_transport_free(struct sctp_transport *transport) sctp_transport_put(transport); } -/* Destroy the transport data structure. - * Assumes there are no more users of this structure. - */ -static void sctp_transport_destroy(struct sctp_transport *transport) +static void sctp_transport_destroy_rcu(struct rcu_head *head) { - SCTP_ASSERT(transport->dead, "Transport is not dead", return); + struct sctp_transport *transport; + transport = container_of(head, struct sctp_transport, rcu); if (transport->asoc) sctp_association_put(transport->asoc); @@ -180,6 +178,16 @@ static void sctp_transport_destroy(struct sctp_transport *transport) SCTP_DBG_OBJCNT_DEC(transport); } +/* Destroy the transport data structure. + * Assumes there are no more users of this structure. + */ +static void sctp_transport_destroy(struct sctp_transport *transport) +{ + SCTP_ASSERT(transport->dead, "Transport is not dead", return); + + call_rcu(&transport->rcu, sctp_transport_destroy_rcu); +} + /* Start T3_rtx timer if it is not already running and update the heartbeat * timer. This routine is called every time a DATA chunk is sent. */ @@ -363,6 +371,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) if (tp->rto > tp->asoc->rto_max) tp->rto = tp->asoc->rto_max; + sctp_max_rto(tp->asoc, tp); tp->rtt = rtt; /* Reset rto_pending so that a new RTT measurement is started when a @@ -620,6 +629,7 @@ void sctp_transport_reset(struct sctp_transport *t) t->burst_limited = 0; t->ssthresh = asoc->peer.i.a_rwnd; t->rto = asoc->rto_initial; + sctp_max_rto(asoc, t); t->rtt = 0; t->srtt = 0; t->rttvar = 0; |