diff options
Diffstat (limited to 'net/dccp/timer.c')
-rw-r--r-- | net/dccp/timer.c | 110 |
1 files changed, 53 insertions, 57 deletions
diff --git a/net/dccp/timer.c b/net/dccp/timer.c index 7b3f16e29a97..e8f519e7f481 100644 --- a/net/dccp/timer.c +++ b/net/dccp/timer.c | |||
@@ -20,16 +20,6 @@ int sysctl_dccp_request_retries __read_mostly = TCP_SYN_RETRIES; | |||
20 | int sysctl_dccp_retries1 __read_mostly = TCP_RETR1; | 20 | int sysctl_dccp_retries1 __read_mostly = TCP_RETR1; |
21 | int sysctl_dccp_retries2 __read_mostly = TCP_RETR2; | 21 | int sysctl_dccp_retries2 __read_mostly = TCP_RETR2; |
22 | 22 | ||
23 | static void dccp_write_timer(unsigned long data); | ||
24 | static void dccp_keepalive_timer(unsigned long data); | ||
25 | static void dccp_delack_timer(unsigned long data); | ||
26 | |||
27 | void dccp_init_xmit_timers(struct sock *sk) | ||
28 | { | ||
29 | inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer, | ||
30 | &dccp_keepalive_timer); | ||
31 | } | ||
32 | |||
33 | static void dccp_write_err(struct sock *sk) | 23 | static void dccp_write_err(struct sock *sk) |
34 | { | 24 | { |
35 | sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; | 25 | sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT; |
@@ -90,53 +80,6 @@ static int dccp_write_timeout(struct sock *sk) | |||
90 | return 0; | 80 | return 0; |
91 | } | 81 | } |
92 | 82 | ||
93 | /* This is the same as tcp_delack_timer, sans prequeue & mem_reclaim stuff */ | ||
94 | static void dccp_delack_timer(unsigned long data) | ||
95 | { | ||
96 | struct sock *sk = (struct sock *)data; | ||
97 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
98 | |||
99 | bh_lock_sock(sk); | ||
100 | if (sock_owned_by_user(sk)) { | ||
101 | /* Try again later. */ | ||
102 | icsk->icsk_ack.blocked = 1; | ||
103 | NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOCKED); | ||
104 | sk_reset_timer(sk, &icsk->icsk_delack_timer, | ||
105 | jiffies + TCP_DELACK_MIN); | ||
106 | goto out; | ||
107 | } | ||
108 | |||
109 | if (sk->sk_state == DCCP_CLOSED || | ||
110 | !(icsk->icsk_ack.pending & ICSK_ACK_TIMER)) | ||
111 | goto out; | ||
112 | if (time_after(icsk->icsk_ack.timeout, jiffies)) { | ||
113 | sk_reset_timer(sk, &icsk->icsk_delack_timer, | ||
114 | icsk->icsk_ack.timeout); | ||
115 | goto out; | ||
116 | } | ||
117 | |||
118 | icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER; | ||
119 | |||
120 | if (inet_csk_ack_scheduled(sk)) { | ||
121 | if (!icsk->icsk_ack.pingpong) { | ||
122 | /* Delayed ACK missed: inflate ATO. */ | ||
123 | icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1, | ||
124 | icsk->icsk_rto); | ||
125 | } else { | ||
126 | /* Delayed ACK missed: leave pingpong mode and | ||
127 | * deflate ATO. | ||
128 | */ | ||
129 | icsk->icsk_ack.pingpong = 0; | ||
130 | icsk->icsk_ack.ato = TCP_ATO_MIN; | ||
131 | } | ||
132 | dccp_send_ack(sk); | ||
133 | NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKS); | ||
134 | } | ||
135 | out: | ||
136 | bh_unlock_sock(sk); | ||
137 | sock_put(sk); | ||
138 | } | ||
139 | |||
140 | /* | 83 | /* |
141 | * The DCCP retransmit timer. | 84 | * The DCCP retransmit timer. |
142 | */ | 85 | */ |
@@ -270,3 +213,56 @@ out: | |||
270 | bh_unlock_sock(sk); | 213 | bh_unlock_sock(sk); |
271 | sock_put(sk); | 214 | sock_put(sk); |
272 | } | 215 | } |
216 | |||
217 | /* This is the same as tcp_delack_timer, sans prequeue & mem_reclaim stuff */ | ||
218 | static void dccp_delack_timer(unsigned long data) | ||
219 | { | ||
220 | struct sock *sk = (struct sock *)data; | ||
221 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
222 | |||
223 | bh_lock_sock(sk); | ||
224 | if (sock_owned_by_user(sk)) { | ||
225 | /* Try again later. */ | ||
226 | icsk->icsk_ack.blocked = 1; | ||
227 | NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOCKED); | ||
228 | sk_reset_timer(sk, &icsk->icsk_delack_timer, | ||
229 | jiffies + TCP_DELACK_MIN); | ||
230 | goto out; | ||
231 | } | ||
232 | |||
233 | if (sk->sk_state == DCCP_CLOSED || | ||
234 | !(icsk->icsk_ack.pending & ICSK_ACK_TIMER)) | ||
235 | goto out; | ||
236 | if (time_after(icsk->icsk_ack.timeout, jiffies)) { | ||
237 | sk_reset_timer(sk, &icsk->icsk_delack_timer, | ||
238 | icsk->icsk_ack.timeout); | ||
239 | goto out; | ||
240 | } | ||
241 | |||
242 | icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER; | ||
243 | |||
244 | if (inet_csk_ack_scheduled(sk)) { | ||
245 | if (!icsk->icsk_ack.pingpong) { | ||
246 | /* Delayed ACK missed: inflate ATO. */ | ||
247 | icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1, | ||
248 | icsk->icsk_rto); | ||
249 | } else { | ||
250 | /* Delayed ACK missed: leave pingpong mode and | ||
251 | * deflate ATO. | ||
252 | */ | ||
253 | icsk->icsk_ack.pingpong = 0; | ||
254 | icsk->icsk_ack.ato = TCP_ATO_MIN; | ||
255 | } | ||
256 | dccp_send_ack(sk); | ||
257 | NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKS); | ||
258 | } | ||
259 | out: | ||
260 | bh_unlock_sock(sk); | ||
261 | sock_put(sk); | ||
262 | } | ||
263 | |||
264 | void dccp_init_xmit_timers(struct sock *sk) | ||
265 | { | ||
266 | inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer, | ||
267 | &dccp_keepalive_timer); | ||
268 | } | ||