On Mon, Apr 18, 2016 at 05:06:57PM -0700, Eric Dumazet wrote:
> It should only be a request from user space to ask TCP to not aggregate
> stuff on future sendpage()/sendmsg() on the skb carrying this new flag.
>
How about something like this.  Please advise if tcp_sendmsg_noappend can
be simpler.

diff --git a/include/net/tcp.h b/include/net/tcp.h
index c0ef054..ac31798 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -762,7 +762,8 @@ struct tcp_skb_cb {

        __u8            ip_dsfield;     /* IPv4 tos or IPv6 dsfield     */
        __u8            txstamp_ack:1,  /* Record TX timestamp for ack? */
-                       unused:7;
+                       eor:1,          /* Is skb MSG_EOR marked */
+                       unused:6;
        __u32           ack_seq;        /* Sequence number ACK'd        */
        union {
                struct inet_skb_parm    h4;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4d73858..12772be 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -874,6 +874,13 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, 
int flags)
        return mss_now;
 }

+static bool tcp_sendmsg_noappend(const struct sock *sk)
+{
+       const struct sk_buff *skb = tcp_write_queue_tail(sk);
+
+       return (!skb || TCP_SKB_CB(skb)->eor);
+}
+
 static ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset,
                                size_t size, int flags)
 {
@@ -903,6 +910,9 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct 
page *page, int offset,
        if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
                goto out_err;

+       if (tcp_sendmsg_noappend(sk))
+               goto new_segment;
+
        while (size > 0) {
                struct sk_buff *skb = tcp_write_queue_tail(sk);
                int copy, i;
@@ -960,6 +970,7 @@ new_segment:
                size -= copy;
                if (!size) {
                        tcp_tx_timestamp(sk, sk->sk_tsflags, skb);
+                       TCP_SKB_CB(skb)->eor = !!(flags & MSG_EOR);
                        goto out;
                }

@@ -1145,6 +1156,9 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, 
size_t size)

        sg = !!(sk->sk_route_caps & NETIF_F_SG);

+       if (tcp_sendmsg_noappend(sk))
+               goto new_segment;
+
        while (msg_data_left(msg)) {
                int copy = 0;
                int max = size_goal;
@@ -1250,6 +1264,7 @@ new_segment:
                copied += copy;
                if (!msg_data_left(msg)) {
                        tcp_tx_timestamp(sk, sockc.tsflags, skb);
+                       TCP_SKB_CB(skb)->eor = !!(flags & MSG_EOR);
                        goto out;
                }

--
2.5.1

Reply via email to