[NET] Introduce sk_reset_timer and sk_stop_timer

This makes the best practices already in place in bluetooth
and tcp/ip available for all protocols, i.e. references must
be managed when associating timers with struct sock instances,
also makes the code a bit more clean.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@conectiva.com.br>
parent 2e5ae683
...@@ -898,6 +898,11 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) ...@@ -898,6 +898,11 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
atomic_add(skb->truesize, &sk->sk_rmem_alloc); atomic_add(skb->truesize, &sk->sk_rmem_alloc);
} }
extern void sk_reset_timer(struct sock *sk, struct timer_list* timer,
unsigned long expires);
extern void sk_stop_timer(struct sock *sk, struct timer_list* timer);
static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{ {
int err = 0; int err = 0;
......
...@@ -989,9 +989,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what) ...@@ -989,9 +989,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
tp->pending = 0; tp->pending = 0;
#ifdef TCP_CLEAR_TIMERS #ifdef TCP_CLEAR_TIMERS
if (timer_pending(&tp->retransmit_timer) && sk_stop_timer(sk, &tp->retransmit_timer);
del_timer(&tp->retransmit_timer))
__sock_put(sk);
#endif #endif
break; break;
case TCP_TIME_DACK: case TCP_TIME_DACK:
...@@ -999,9 +997,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what) ...@@ -999,9 +997,7 @@ static inline void tcp_clear_xmit_timer(struct sock *sk, int what)
tp->ack.pending = 0; tp->ack.pending = 0;
#ifdef TCP_CLEAR_TIMERS #ifdef TCP_CLEAR_TIMERS
if (timer_pending(&tp->delack_timer) && sk_stop_timer(sk, &tp->delack_timer);
del_timer(&tp->delack_timer))
__sock_put(sk);
#endif #endif
break; break;
default: default:
...@@ -1030,15 +1026,13 @@ static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long ...@@ -1030,15 +1026,13 @@ static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long
case TCP_TIME_PROBE0: case TCP_TIME_PROBE0:
tp->pending = what; tp->pending = what;
tp->timeout = jiffies+when; tp->timeout = jiffies+when;
if (!mod_timer(&tp->retransmit_timer, tp->timeout)) sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
sock_hold(sk);
break; break;
case TCP_TIME_DACK: case TCP_TIME_DACK:
tp->ack.pending |= TCP_ACK_TIMER; tp->ack.pending |= TCP_ACK_TIMER;
tp->ack.timeout = jiffies+when; tp->ack.timeout = jiffies+when;
if (!mod_timer(&tp->delack_timer, tp->ack.timeout)) sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
sock_hold(sk);
break; break;
default: default:
......
...@@ -95,17 +95,13 @@ static void l2cap_sock_timeout(unsigned long arg) ...@@ -95,17 +95,13 @@ static void l2cap_sock_timeout(unsigned long arg)
static void l2cap_sock_set_timer(struct sock *sk, long timeout) static void l2cap_sock_set_timer(struct sock *sk, long timeout)
{ {
BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout);
sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
if (!mod_timer(&sk->sk_timer, jiffies + timeout))
sock_hold(sk);
} }
static void l2cap_sock_clear_timer(struct sock *sk) static void l2cap_sock_clear_timer(struct sock *sk)
{ {
BT_DBG("sock %p state %d", sk, sk->sk_state); BT_DBG("sock %p state %d", sk, sk->sk_state);
sk_stop_timer(sk, &sk->sk_timer);
if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
__sock_put(sk);
} }
static void l2cap_sock_init_timer(struct sock *sk) static void l2cap_sock_init_timer(struct sock *sk)
......
...@@ -91,17 +91,13 @@ static void sco_sock_timeout(unsigned long arg) ...@@ -91,17 +91,13 @@ static void sco_sock_timeout(unsigned long arg)
static void sco_sock_set_timer(struct sock *sk, long timeout) static void sco_sock_set_timer(struct sock *sk, long timeout)
{ {
BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout); BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout);
sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout);
if (!mod_timer(&sk->sk_timer, jiffies + timeout))
sock_hold(sk);
} }
static void sco_sock_clear_timer(struct sock *sk) static void sco_sock_clear_timer(struct sock *sk)
{ {
BT_DBG("sock %p state %d", sk, sk->sk_state); BT_DBG("sock %p state %d", sk, sk->sk_state);
sk_stop_timer(sk, &sk->sk_timer);
if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer))
__sock_put(sk);
} }
static void sco_sock_init_timer(struct sock *sk) static void sco_sock_init_timer(struct sock *sk)
......
...@@ -1099,6 +1099,23 @@ void sk_send_sigurg(struct sock *sk) ...@@ -1099,6 +1099,23 @@ void sk_send_sigurg(struct sock *sk)
sk_wake_async(sk, 3, POLL_PRI); sk_wake_async(sk, 3, POLL_PRI);
} }
void sk_reset_timer(struct sock *sk, struct timer_list* timer,
unsigned long expires)
{
if (!mod_timer(timer, expires))
sock_hold(sk);
}
EXPORT_SYMBOL(sk_reset_timer);
void sk_stop_timer(struct sock *sk, struct timer_list* timer)
{
if (timer_pending(timer) && del_timer(timer))
__sock_put(sk);
}
EXPORT_SYMBOL(sk_stop_timer);
void sock_init_data(struct socket *sock, struct sock *sk) void sock_init_data(struct socket *sock, struct sock *sk)
{ {
skb_queue_head_init(&sk->sk_receive_queue); skb_queue_head_init(&sk->sk_receive_queue);
......
...@@ -1389,8 +1389,7 @@ void tcp_send_delayed_ack(struct sock *sk) ...@@ -1389,8 +1389,7 @@ void tcp_send_delayed_ack(struct sock *sk)
} }
tp->ack.pending |= TCP_ACK_SCHED|TCP_ACK_TIMER; tp->ack.pending |= TCP_ACK_SCHED|TCP_ACK_TIMER;
tp->ack.timeout = timeout; tp->ack.timeout = timeout;
if (!mod_timer(&tp->delack_timer, timeout)) sk_reset_timer(sk, &tp->delack_timer, timeout);
sock_hold(sk);
} }
/* This routine sends an ack and also updates the window. */ /* This routine sends an ack and also updates the window. */
......
...@@ -68,18 +68,13 @@ void tcp_clear_xmit_timers(struct sock *sk) ...@@ -68,18 +68,13 @@ void tcp_clear_xmit_timers(struct sock *sk)
struct tcp_opt *tp = tcp_sk(sk); struct tcp_opt *tp = tcp_sk(sk);
tp->pending = 0; tp->pending = 0;
if (timer_pending(&tp->retransmit_timer) && sk_stop_timer(sk, &tp->retransmit_timer);
del_timer(&tp->retransmit_timer))
__sock_put(sk);
tp->ack.pending = 0; tp->ack.pending = 0;
tp->ack.blocked = 0; tp->ack.blocked = 0;
if (timer_pending(&tp->delack_timer) && sk_stop_timer(sk, &tp->delack_timer);
del_timer(&tp->delack_timer))
__sock_put(sk);
if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer)) sk_stop_timer(sk, &sk->sk_timer);
__sock_put(sk);
} }
static void tcp_write_err(struct sock *sk) static void tcp_write_err(struct sock *sk)
...@@ -218,8 +213,7 @@ static void tcp_delack_timer(unsigned long data) ...@@ -218,8 +213,7 @@ static void tcp_delack_timer(unsigned long data)
/* Try again later. */ /* Try again later. */
tp->ack.blocked = 1; tp->ack.blocked = 1;
NET_INC_STATS_BH(DelayedACKLocked); NET_INC_STATS_BH(DelayedACKLocked);
if (!mod_timer(&tp->delack_timer, jiffies + TCP_DELACK_MIN)) sk_reset_timer(sk, &tp->delack_timer, jiffies + TCP_DELACK_MIN);
sock_hold(sk);
goto out_unlock; goto out_unlock;
} }
...@@ -229,8 +223,7 @@ static void tcp_delack_timer(unsigned long data) ...@@ -229,8 +223,7 @@ static void tcp_delack_timer(unsigned long data)
goto out; goto out;
if (time_after(tp->ack.timeout, jiffies)) { if (time_after(tp->ack.timeout, jiffies)) {
if (!mod_timer(&tp->delack_timer, tp->ack.timeout)) sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout);
sock_hold(sk);
goto out; goto out;
} }
tp->ack.pending &= ~TCP_ACK_TIMER; tp->ack.pending &= ~TCP_ACK_TIMER;
...@@ -429,8 +422,7 @@ static void tcp_write_timer(unsigned long data) ...@@ -429,8 +422,7 @@ static void tcp_write_timer(unsigned long data)
bh_lock_sock(sk); bh_lock_sock(sk);
if (sock_owned_by_user(sk)) { if (sock_owned_by_user(sk)) {
/* Try again later */ /* Try again later */
if (!mod_timer(&tp->retransmit_timer, jiffies + (HZ/20))) sk_reset_timer(sk, &tp->retransmit_timer, jiffies + (HZ / 20));
sock_hold(sk);
goto out_unlock; goto out_unlock;
} }
...@@ -438,8 +430,7 @@ static void tcp_write_timer(unsigned long data) ...@@ -438,8 +430,7 @@ static void tcp_write_timer(unsigned long data)
goto out; goto out;
if (time_after(tp->timeout, jiffies)) { if (time_after(tp->timeout, jiffies)) {
if (!mod_timer(&tp->retransmit_timer, tp->timeout)) sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout);
sock_hold(sk);
goto out; goto out;
} }
...@@ -557,14 +548,12 @@ static void tcp_synack_timer(struct sock *sk) ...@@ -557,14 +548,12 @@ static void tcp_synack_timer(struct sock *sk)
void tcp_delete_keepalive_timer (struct sock *sk) void tcp_delete_keepalive_timer (struct sock *sk)
{ {
if (timer_pending(&sk->sk_timer) && del_timer (&sk->sk_timer)) sk_stop_timer(sk, &sk->sk_timer);
__sock_put(sk);
} }
void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len) void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len)
{ {
if (!mod_timer(&sk->sk_timer, jiffies + len)) sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
sock_hold(sk);
} }
void tcp_set_keepalive(struct sock *sk, int val) void tcp_set_keepalive(struct sock *sk, int val)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment