strparser: Generalize strparser

Generalize strparser from more than just being used in conjunction
with read_sock. strparser will also be used in the send path with
zero proxy. The primary change is to create strp_process function
that performs the critical processing on skbs. The documentation
is also updated to reflect the new uses.

Signed-off-by: Tom Herbert <tom@quantonium.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Tom Herbert
2017-07-28 16:22:43 -07:00
committed by David S. Miller
parent 20bf50de30
commit bbb03029a8
5 changed files with 424 additions and 287 deletions

View File

@@ -155,8 +155,8 @@ static void kcm_format_psock(struct kcm_psock *psock, struct seq_file *seq,
seq_printf(seq,
" psock-%-5u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8d ",
psock->index,
psock->strp.stats.rx_msgs,
psock->strp.stats.rx_bytes,
psock->strp.stats.msgs,
psock->strp.stats.bytes,
psock->stats.tx_msgs,
psock->stats.tx_bytes,
psock->sk->sk_receive_queue.qlen,
@@ -170,22 +170,22 @@ static void kcm_format_psock(struct kcm_psock *psock, struct seq_file *seq,
if (psock->tx_stopped)
seq_puts(seq, "TxStop ");
if (psock->strp.rx_stopped)
if (psock->strp.stopped)
seq_puts(seq, "RxStop ");
if (psock->tx_kcm)
seq_printf(seq, "Rsvd-%d ", psock->tx_kcm->index);
if (!psock->strp.rx_paused && !psock->ready_rx_msg) {
if (!psock->strp.paused && !psock->ready_rx_msg) {
if (psock->sk->sk_receive_queue.qlen) {
if (psock->strp.rx_need_bytes)
if (psock->strp.need_bytes)
seq_printf(seq, "RxWait=%u ",
psock->strp.rx_need_bytes);
psock->strp.need_bytes);
else
seq_printf(seq, "RxWait ");
}
} else {
if (psock->strp.rx_paused)
if (psock->strp.paused)
seq_puts(seq, "RxPause ");
if (psock->ready_rx_msg)
@@ -371,20 +371,20 @@ static int kcm_stats_seq_show(struct seq_file *seq, void *v)
seq_printf(seq,
"%-8s %-10llu %-16llu %-10llu %-16llu %-10llu %-10llu %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u\n",
"",
strp_stats.rx_msgs,
strp_stats.rx_bytes,
strp_stats.msgs,
strp_stats.bytes,
psock_stats.tx_msgs,
psock_stats.tx_bytes,
psock_stats.reserved,
psock_stats.unreserved,
strp_stats.rx_aborts,
strp_stats.rx_interrupted,
strp_stats.rx_unrecov_intr,
strp_stats.rx_mem_fail,
strp_stats.rx_need_more_hdr,
strp_stats.rx_bad_hdr_len,
strp_stats.rx_msg_too_big,
strp_stats.rx_msg_timeouts,
strp_stats.aborts,
strp_stats.interrupted,
strp_stats.unrecov_intr,
strp_stats.mem_fail,
strp_stats.need_more_hdr,
strp_stats.bad_hdr_len,
strp_stats.msg_too_big,
strp_stats.msg_timeouts,
psock_stats.tx_aborts);
return 0;

View File

@@ -96,12 +96,12 @@ static void kcm_update_rx_mux_stats(struct kcm_mux *mux,
struct kcm_psock *psock)
{
STRP_STATS_ADD(mux->stats.rx_bytes,
psock->strp.stats.rx_bytes -
psock->strp.stats.bytes -
psock->saved_rx_bytes);
mux->stats.rx_msgs +=
psock->strp.stats.rx_msgs - psock->saved_rx_msgs;
psock->saved_rx_msgs = psock->strp.stats.rx_msgs;
psock->saved_rx_bytes = psock->strp.stats.rx_bytes;
psock->strp.stats.msgs - psock->saved_rx_msgs;
psock->saved_rx_msgs = psock->strp.stats.msgs;
psock->saved_rx_bytes = psock->strp.stats.bytes;
}
static void kcm_update_tx_mux_stats(struct kcm_mux *mux,
@@ -1118,7 +1118,7 @@ static int kcm_recvmsg(struct socket *sock, struct msghdr *msg,
struct kcm_sock *kcm = kcm_sk(sk);
int err = 0;
long timeo;
struct strp_rx_msg *rxm;
struct strp_msg *stm;
int copied = 0;
struct sk_buff *skb;
@@ -1132,26 +1132,26 @@ static int kcm_recvmsg(struct socket *sock, struct msghdr *msg,
/* Okay, have a message on the receive queue */
rxm = strp_rx_msg(skb);
stm = strp_msg(skb);
if (len > rxm->full_len)
len = rxm->full_len;
if (len > stm->full_len)
len = stm->full_len;
err = skb_copy_datagram_msg(skb, rxm->offset, msg, len);
err = skb_copy_datagram_msg(skb, stm->offset, msg, len);
if (err < 0)
goto out;
copied = len;
if (likely(!(flags & MSG_PEEK))) {
KCM_STATS_ADD(kcm->stats.rx_bytes, copied);
if (copied < rxm->full_len) {
if (copied < stm->full_len) {
if (sock->type == SOCK_DGRAM) {
/* Truncated message */
msg->msg_flags |= MSG_TRUNC;
goto msg_finished;
}
rxm->offset += copied;
rxm->full_len -= copied;
stm->offset += copied;
stm->full_len -= copied;
} else {
msg_finished:
/* Finished with message */
@@ -1175,7 +1175,7 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
struct sock *sk = sock->sk;
struct kcm_sock *kcm = kcm_sk(sk);
long timeo;
struct strp_rx_msg *rxm;
struct strp_msg *stm;
int err = 0;
ssize_t copied;
struct sk_buff *skb;
@@ -1192,12 +1192,12 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
/* Okay, have a message on the receive queue */
rxm = strp_rx_msg(skb);
stm = strp_msg(skb);
if (len > rxm->full_len)
len = rxm->full_len;
if (len > stm->full_len)
len = stm->full_len;
copied = skb_splice_bits(skb, sk, rxm->offset, pipe, len, flags);
copied = skb_splice_bits(skb, sk, stm->offset, pipe, len, flags);
if (copied < 0) {
err = copied;
goto err_out;
@@ -1205,8 +1205,8 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
KCM_STATS_ADD(kcm->stats.rx_bytes, copied);
rxm->offset += copied;
rxm->full_len -= copied;
stm->offset += copied;
stm->full_len -= copied;
/* We have no way to return MSG_EOR. If all the bytes have been
* read we still leave the message in the receive socket buffer.