sctp: remove the dead field of sctp_transport

After we use refcnt to check if transport is alive, the dead can be
removed from sctp_transport.

The traversal of transport_addr_list in procfs dump is using
list_for_each_entry_rcu, no need to check if it has been freed.

sctp_generate_t3_rtx_event and sctp_generate_heartbeat_event is
protected by sock lock, it's not necessary to check dead, either.
also, the timers are cancelled when sctp_transport_free() is
called, that it doesn't wait for refcnt to reach 0 to cancel them.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Xin Long 2016-01-22 01:49:09 +08:00 committed by David S. Miller
parent fba4c330c5
commit 47faa1e4c5
4 changed files with 2 additions and 21 deletions

View File

@ -756,7 +756,6 @@ struct sctp_transport {
/* Reference counting. */ /* Reference counting. */
atomic_t refcnt; atomic_t refcnt;
__u32 dead:1,
/* RTO-Pending : A flag used to track if one of the DATA /* RTO-Pending : A flag used to track if one of the DATA
* chunks sent to this address is currently being * chunks sent to this address is currently being
* used to compute a RTT. If this flag is 0, * used to compute a RTT. If this flag is 0,
@ -766,7 +765,7 @@ struct sctp_transport {
* calculation completes (i.e. the DATA chunk * calculation completes (i.e. the DATA chunk
* is SACK'd) clear this flag. * is SACK'd) clear this flag.
*/ */
rto_pending:1, __u32 rto_pending:1,
/* /*
* hb_sent : a flag that signals that we have a pending * hb_sent : a flag that signals that we have a pending

View File

@ -165,8 +165,6 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa
list_for_each_entry_rcu(transport, &assoc->peer.transport_addr_list, list_for_each_entry_rcu(transport, &assoc->peer.transport_addr_list,
transports) { transports) {
addr = &transport->ipaddr; addr = &transport->ipaddr;
if (transport->dead)
continue;
af = sctp_get_af_specific(addr->sa.sa_family); af = sctp_get_af_specific(addr->sa.sa_family);
if (af->cmp_addr(addr, primary)) { if (af->cmp_addr(addr, primary)) {
@ -499,8 +497,6 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
list_for_each_entry_rcu(tsp, &assoc->peer.transport_addr_list, list_for_each_entry_rcu(tsp, &assoc->peer.transport_addr_list,
transports) { transports) {
if (tsp->dead)
continue;
/* /*
* The remote address (ADDR) * The remote address (ADDR)
*/ */

View File

@ -259,12 +259,6 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
goto out_unlock; goto out_unlock;
} }
/* Is this transport really dead and just waiting around for
* the timer to let go of the reference?
*/
if (transport->dead)
goto out_unlock;
/* Run through the state machine. */ /* Run through the state machine. */
error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT, error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_T3_RTX), SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_T3_RTX),
@ -380,12 +374,6 @@ void sctp_generate_heartbeat_event(unsigned long data)
goto out_unlock; goto out_unlock;
} }
/* Is this structure just waiting around for us to actually
* get destroyed?
*/
if (transport->dead)
goto out_unlock;
error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT, error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_HEARTBEAT), SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_HEARTBEAT),
asoc->state, asoc->ep, asoc, asoc->state, asoc->ep, asoc,

View File

@ -132,8 +132,6 @@ struct sctp_transport *sctp_transport_new(struct net *net,
*/ */
void sctp_transport_free(struct sctp_transport *transport) void sctp_transport_free(struct sctp_transport *transport)
{ {
transport->dead = 1;
/* Try to delete the heartbeat timer. */ /* Try to delete the heartbeat timer. */
if (del_timer(&transport->hb_timer)) if (del_timer(&transport->hb_timer))
sctp_transport_put(transport); sctp_transport_put(transport);
@ -169,7 +167,7 @@ static void sctp_transport_destroy_rcu(struct rcu_head *head)
*/ */
static void sctp_transport_destroy(struct sctp_transport *transport) static void sctp_transport_destroy(struct sctp_transport *transport)
{ {
if (unlikely(!transport->dead)) { if (unlikely(atomic_read(&transport->refcnt))) {
WARN(1, "Attempt to destroy undead transport %p!\n", transport); WARN(1, "Attempt to destroy undead transport %p!\n", transport);
return; return;
} }