diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index b0447c33d..e34d1e7b5 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -196,6 +196,7 @@ static int llc_ui_release(struct socket *sock) { struct sock *sk = sock->sk; struct llc_sock *llc; + struct llc_sap *sap = NULL; if (unlikely(sk == NULL)) goto out; @@ -207,23 +208,21 @@ static int llc_ui_release(struct socket *sock) if (!llc_send_disc(sk)) llc_ui_wait_for_disc(sk, READ_ONCE(sk->sk_rcvtimeo)); if (!sock_flag(sk, SOCK_ZAPPED)) { - struct llc_sap *sap = llc->sap; + sap = llc->sap; - /* Hold this for release_sock(), so that llc_backlog_rcv() - * could still use it. - */ + /* Keep SAP alive through backlog processing and timer shutdown. */ llc_sap_hold(sap); llc_sap_remove_socket(llc->sap, sk); release_sock(sk); - llc_sap_put(sap); } else { release_sock(sk); } - netdev_put(llc->dev, &llc->dev_tracker); sock_put(sk); sock_orphan(sk); sock->sk = NULL; llc_sk_free(sk); + if (sap) + llc_sap_put(sap); out: return 0; } diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 260460d50..2ad5a69dd 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -942,10 +942,10 @@ void llc_sk_stop_all_timers(struct sock *sk, bool sync) struct llc_sock *llc = llc_sk(sk); if (sync) { - timer_delete_sync(&llc->pf_cycle_timer.timer); - timer_delete_sync(&llc->ack_timer.timer); - timer_delete_sync(&llc->rej_sent_timer.timer); - timer_delete_sync(&llc->busy_state_timer.timer); + timer_shutdown_sync(&llc->pf_cycle_timer.timer); + timer_shutdown_sync(&llc->ack_timer.timer); + timer_shutdown_sync(&llc->rej_sent_timer.timer); + timer_shutdown_sync(&llc->busy_state_timer.timer); } else { timer_delete(&llc->pf_cycle_timer.timer); timer_delete(&llc->ack_timer.timer); @@ -978,6 +978,7 @@ void llc_sk_free(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); skb_queue_purge(&llc->pdu_unack_q); + netdev_put(llc->dev, &llc->dev_tracker); #ifdef LLC_REFCNT_DEBUG if (refcount_read(&sk->sk_refcnt) != 1) { printk(KERN_DEBUG "Destruction of LLC sock %p delayed in %s, cnt=%d\n",