Skip to content

Commit cb225e8

Browse files
congwanggregkh
authored andcommitted
llc: delete timers synchronously in llc_sk_free()
[ Upstream commit b905ef9 ] The connection timers of an llc sock could be still flying after we delete them in llc_sk_free(), and even possibly after we free the sock. We could just wait synchronously here in case of troubles. Note, I leave other call paths as they are, since they may not have to wait, at least we can change them to synchronously when needed. Also, move the code to net/llc/llc_conn.c, which is apparently a better place. Reported-by: <[email protected]> Signed-off-by: Cong Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 15efa78 commit cb225e8

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

include/net/llc_conn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ static __inline__ char llc_backlog_type(struct sk_buff *skb)
9797

9898
struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
9999
struct proto *prot, int kern);
100+
void llc_sk_stop_all_timers(struct sock *sk, bool sync);
100101
void llc_sk_free(struct sock *sk);
101102

102103
void llc_sk_reset(struct sock *sk);

net/llc/llc_c_ac.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,14 +1096,7 @@ int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb)
10961096

10971097
int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
10981098
{
1099-
struct llc_sock *llc = llc_sk(sk);
1100-
1101-
del_timer(&llc->pf_cycle_timer.timer);
1102-
del_timer(&llc->ack_timer.timer);
1103-
del_timer(&llc->rej_sent_timer.timer);
1104-
del_timer(&llc->busy_state_timer.timer);
1105-
llc->ack_must_be_send = 0;
1106-
llc->ack_pf = 0;
1099+
llc_sk_stop_all_timers(sk, false);
11071100
return 0;
11081101
}
11091102

net/llc/llc_conn.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,26 @@ struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct pr
951951
return sk;
952952
}
953953

954+
void llc_sk_stop_all_timers(struct sock *sk, bool sync)
955+
{
956+
struct llc_sock *llc = llc_sk(sk);
957+
958+
if (sync) {
959+
del_timer_sync(&llc->pf_cycle_timer.timer);
960+
del_timer_sync(&llc->ack_timer.timer);
961+
del_timer_sync(&llc->rej_sent_timer.timer);
962+
del_timer_sync(&llc->busy_state_timer.timer);
963+
} else {
964+
del_timer(&llc->pf_cycle_timer.timer);
965+
del_timer(&llc->ack_timer.timer);
966+
del_timer(&llc->rej_sent_timer.timer);
967+
del_timer(&llc->busy_state_timer.timer);
968+
}
969+
970+
llc->ack_must_be_send = 0;
971+
llc->ack_pf = 0;
972+
}
973+
954974
/**
955975
* llc_sk_free - Frees a LLC socket
956976
* @sk - socket to free
@@ -963,7 +983,7 @@ void llc_sk_free(struct sock *sk)
963983

964984
llc->state = LLC_CONN_OUT_OF_SVC;
965985
/* Stop all (possibly) running timers */
966-
llc_conn_ac_stop_all_timers(sk, NULL);
986+
llc_sk_stop_all_timers(sk, true);
967987
#ifdef DEBUG_LLC_CONN_ALLOC
968988
printk(KERN_INFO "%s: unackq=%d, txq=%d\n", __func__,
969989
skb_queue_len(&llc->pdu_unack_q),

0 commit comments

Comments
 (0)