aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Herbert <tom@herbertland.com>2016-03-07 17:11:11 -0500
committerDavid S. Miller <davem@davemloft.net>2016-03-09 16:36:15 -0500
commit29152a34f72cb4d7ab32885ad2f20a482c92a8f3 (patch)
tree89287b971525eab8a238437e3e12959074f9fa63
parent7ced95ef525c329f947c424859cf2b0a3b731f8c (diff)
kcm: Add receive message timeout
This patch adds receive timeout for message assembly on the attached TCP sockets. The timeout is set when a new messages is started and the whole message has not been received by TCP (not in the receive queue). If the completely message is subsequently received the timer is cancelled, if the timer expires the RX side is aborted. The timeout value is taken from the socket timeout (SO_RCVTIMEO) that is set on a TCP socket (i.e. set by get sockopt before attaching a TCP socket to KCM. Signed-off-by: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/kcm.h3
-rw-r--r--net/kcm/kcmproc.c6
-rw-r--r--net/kcm/kcmsock.c32
3 files changed, 39 insertions, 2 deletions
diff --git a/include/net/kcm.h b/include/net/kcm.h
index d892956ff552..95c425ca97b6 100644
--- a/include/net/kcm.h
+++ b/include/net/kcm.h
@@ -29,6 +29,7 @@ struct kcm_psock_stats {
29 unsigned int rx_mem_fail; 29 unsigned int rx_mem_fail;
30 unsigned int rx_need_more_hdr; 30 unsigned int rx_need_more_hdr;
31 unsigned int rx_msg_too_big; 31 unsigned int rx_msg_too_big;
32 unsigned int rx_msg_timeouts;
32 unsigned int rx_bad_hdr_len; 33 unsigned int rx_bad_hdr_len;
33 unsigned long long reserved; 34 unsigned long long reserved;
34 unsigned long long unreserved; 35 unsigned long long unreserved;
@@ -130,6 +131,7 @@ struct kcm_psock {
130 struct kcm_sock *rx_kcm; 131 struct kcm_sock *rx_kcm;
131 unsigned long long saved_rx_bytes; 132 unsigned long long saved_rx_bytes;
132 unsigned long long saved_rx_msgs; 133 unsigned long long saved_rx_msgs;
134 struct timer_list rx_msg_timer;
133 unsigned int rx_need_bytes; 135 unsigned int rx_need_bytes;
134 136
135 /* Transmit */ 137 /* Transmit */
@@ -194,6 +196,7 @@ static inline void aggregate_psock_stats(struct kcm_psock_stats *stats,
194 SAVE_PSOCK_STATS(rx_mem_fail); 196 SAVE_PSOCK_STATS(rx_mem_fail);
195 SAVE_PSOCK_STATS(rx_need_more_hdr); 197 SAVE_PSOCK_STATS(rx_need_more_hdr);
196 SAVE_PSOCK_STATS(rx_msg_too_big); 198 SAVE_PSOCK_STATS(rx_msg_too_big);
199 SAVE_PSOCK_STATS(rx_msg_timeouts);
197 SAVE_PSOCK_STATS(rx_bad_hdr_len); 200 SAVE_PSOCK_STATS(rx_bad_hdr_len);
198 SAVE_PSOCK_STATS(tx_msgs); 201 SAVE_PSOCK_STATS(tx_msgs);
199 SAVE_PSOCK_STATS(tx_bytes); 202 SAVE_PSOCK_STATS(tx_bytes);
diff --git a/net/kcm/kcmproc.c b/net/kcm/kcmproc.c
index 7638b3555b17..738008726cc6 100644
--- a/net/kcm/kcmproc.c
+++ b/net/kcm/kcmproc.c
@@ -331,7 +331,7 @@ static int kcm_stats_seq_show(struct seq_file *seq, void *v)
331 mux_stats.rx_ready_drops); 331 mux_stats.rx_ready_drops);
332 332
333 seq_printf(seq, 333 seq_printf(seq,
334 "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s\n", 334 "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s\n",
335 "Psock", 335 "Psock",
336 "RX-Msgs", 336 "RX-Msgs",
337 "RX-Bytes", 337 "RX-Bytes",
@@ -344,10 +344,11 @@ static int kcm_stats_seq_show(struct seq_file *seq, void *v)
344 "RX-NeedMor", 344 "RX-NeedMor",
345 "RX-BadLen", 345 "RX-BadLen",
346 "RX-TooBig", 346 "RX-TooBig",
347 "RX-Timeout",
347 "TX-Aborts"); 348 "TX-Aborts");
348 349
349 seq_printf(seq, 350 seq_printf(seq,
350 "%-8s %-10llu %-16llu %-10llu %-16llu %-10llu %-10llu %-10u %-10u %-10u %-10u %-10u %-10u\n", 351 "%-8s %-10llu %-16llu %-10llu %-16llu %-10llu %-10llu %-10u %-10u %-10u %-10u %-10u %-10u %-10u\n",
351 "", 352 "",
352 psock_stats.rx_msgs, 353 psock_stats.rx_msgs,
353 psock_stats.rx_bytes, 354 psock_stats.rx_bytes,
@@ -360,6 +361,7 @@ static int kcm_stats_seq_show(struct seq_file *seq, void *v)
360 psock_stats.rx_need_more_hdr, 361 psock_stats.rx_need_more_hdr,
361 psock_stats.rx_bad_hdr_len, 362 psock_stats.rx_bad_hdr_len,
362 psock_stats.rx_msg_too_big, 363 psock_stats.rx_msg_too_big,
364 psock_stats.rx_msg_timeouts,
363 psock_stats.tx_aborts); 365 psock_stats.tx_aborts);
364 366
365 return 0; 367 return 0;
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
index 8bc38d3fff9a..40662d73204f 100644
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@ -55,6 +55,8 @@ static void kcm_abort_rx_psock(struct kcm_psock *psock, int err,
55 55
56 /* Unrecoverable error in receive */ 56 /* Unrecoverable error in receive */
57 57
58 del_timer(&psock->rx_msg_timer);
59
58 if (psock->rx_stopped) 60 if (psock->rx_stopped)
59 return; 61 return;
60 62
@@ -351,6 +353,12 @@ static void unreserve_rx_kcm(struct kcm_psock *psock,
351 spin_unlock_bh(&mux->rx_lock); 353 spin_unlock_bh(&mux->rx_lock);
352} 354}
353 355
356static void kcm_start_rx_timer(struct kcm_psock *psock)
357{
358 if (psock->sk->sk_rcvtimeo)
359 mod_timer(&psock->rx_msg_timer, psock->sk->sk_rcvtimeo);
360}
361
354/* Macro to invoke filter function. */ 362/* Macro to invoke filter function. */
355#define KCM_RUN_FILTER(prog, ctx) \ 363#define KCM_RUN_FILTER(prog, ctx) \
356 (*prog->bpf_func)(ctx, prog->insnsi) 364 (*prog->bpf_func)(ctx, prog->insnsi)
@@ -500,6 +508,10 @@ static int kcm_tcp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
500 508
501 if (!len) { 509 if (!len) {
502 /* Need more header to determine length */ 510 /* Need more header to determine length */
511 if (!rxm->accum_len) {
512 /* Start RX timer for new message */
513 kcm_start_rx_timer(psock);
514 }
503 rxm->accum_len += cand_len; 515 rxm->accum_len += cand_len;
504 eaten += cand_len; 516 eaten += cand_len;
505 KCM_STATS_INCR(psock->stats.rx_need_more_hdr); 517 KCM_STATS_INCR(psock->stats.rx_need_more_hdr);
@@ -540,6 +552,11 @@ static int kcm_tcp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
540 * but don't consume yet per tcp_read_sock. 552 * but don't consume yet per tcp_read_sock.
541 */ 553 */
542 554
555 if (!rxm->accum_len) {
556 /* Start RX timer for new message */
557 kcm_start_rx_timer(psock);
558 }
559
543 psock->rx_need_bytes = rxm->full_len - 560 psock->rx_need_bytes = rxm->full_len -
544 rxm->accum_len; 561 rxm->accum_len;
545 rxm->accum_len += cand_len; 562 rxm->accum_len += cand_len;
@@ -563,6 +580,7 @@ static int kcm_tcp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
563 eaten += (cand_len - extra); 580 eaten += (cand_len - extra);
564 581
565 /* Hurray, we have a new message! */ 582 /* Hurray, we have a new message! */
583 del_timer(&psock->rx_msg_timer);
566 psock->rx_skb_head = NULL; 584 psock->rx_skb_head = NULL;
567 KCM_STATS_INCR(psock->stats.rx_msgs); 585 KCM_STATS_INCR(psock->stats.rx_msgs);
568 586
@@ -1656,6 +1674,15 @@ static void init_kcm_sock(struct kcm_sock *kcm, struct kcm_mux *mux)
1656 spin_unlock_bh(&mux->rx_lock); 1674 spin_unlock_bh(&mux->rx_lock);
1657} 1675}
1658 1676
1677static void kcm_rx_msg_timeout(unsigned long arg)
1678{
1679 struct kcm_psock *psock = (struct kcm_psock *)arg;
1680
1681 /* Message assembly timed out */
1682 KCM_STATS_INCR(psock->stats.rx_msg_timeouts);
1683 kcm_abort_rx_psock(psock, ETIMEDOUT, NULL);
1684}
1685
1659static int kcm_attach(struct socket *sock, struct socket *csock, 1686static int kcm_attach(struct socket *sock, struct socket *csock,
1660 struct bpf_prog *prog) 1687 struct bpf_prog *prog)
1661{ 1688{
@@ -1685,6 +1712,10 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
1685 psock->mux = mux; 1712 psock->mux = mux;
1686 psock->sk = csk; 1713 psock->sk = csk;
1687 psock->bpf_prog = prog; 1714 psock->bpf_prog = prog;
1715
1716 setup_timer(&psock->rx_msg_timer, kcm_rx_msg_timeout,
1717 (unsigned long)psock);
1718
1688 INIT_WORK(&psock->rx_work, psock_rx_work); 1719 INIT_WORK(&psock->rx_work, psock_rx_work);
1689 INIT_DELAYED_WORK(&psock->rx_delayed_work, psock_rx_delayed_work); 1720 INIT_DELAYED_WORK(&psock->rx_delayed_work, psock_rx_delayed_work);
1690 1721
@@ -1796,6 +1827,7 @@ static void kcm_unattach(struct kcm_psock *psock)
1796 1827
1797 write_unlock_bh(&csk->sk_callback_lock); 1828 write_unlock_bh(&csk->sk_callback_lock);
1798 1829
1830 del_timer_sync(&psock->rx_msg_timer);
1799 cancel_work_sync(&psock->rx_work); 1831 cancel_work_sync(&psock->rx_work);
1800 cancel_delayed_work_sync(&psock->rx_delayed_work); 1832 cancel_delayed_work_sync(&psock->rx_delayed_work);
1801 1833