tls: rx: periodically flush socket backlog
authorJakub Kicinski <kuba@kernel.org>
Tue, 5 Jul 2022 23:59:26 +0000 (16:59 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 6 Jul 2022 11:56:35 +0000 (12:56 +0100)
We continuously hold the socket lock during large reads and writes.
This may inflate RTT and negatively impact TCP performance.
Flush the backlog periodically. I tried to pick a flush period (128kB)
which gives significant benefit but the max Bps rate is not yet visibly
impacted.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/sock.c
net/tls/tls_sw.c

index 92a0296..4cb957d 100644 (file)
@@ -2870,6 +2870,7 @@ void __sk_flush_backlog(struct sock *sk)
        __release_sock(sk);
        spin_unlock_bh(&sk->sk_lock.slock);
 }
+EXPORT_SYMBOL_GPL(__sk_flush_backlog);
 
 /**
  * sk_wait_data - wait for data to arrive at sk_receive_queue
index 7592b65..79043bc 100644 (file)
@@ -1738,6 +1738,24 @@ out:
        return copied ? : err;
 }
 
+static void
+tls_read_flush_backlog(struct sock *sk, struct tls_prot_info *prot,
+                      size_t len_left, size_t decrypted, ssize_t done,
+                      size_t *flushed_at)
+{
+       size_t max_rec;
+
+       if (len_left <= decrypted)
+               return;
+
+       max_rec = prot->overhead_size - prot->tail_size + TLS_MAX_PAYLOAD_SIZE;
+       if (done - *flushed_at < SZ_128K && tcp_inq(sk) > max_rec)
+               return;
+
+       *flushed_at = done;
+       sk_flush_backlog(sk);
+}
+
 int tls_sw_recvmsg(struct sock *sk,
                   struct msghdr *msg,
                   size_t len,
@@ -1750,6 +1768,7 @@ int tls_sw_recvmsg(struct sock *sk,
        struct sk_psock *psock;
        unsigned char control = 0;
        ssize_t decrypted = 0;
+       size_t flushed_at = 0;
        struct strp_msg *rxm;
        struct tls_msg *tlm;
        struct sk_buff *skb;
@@ -1839,6 +1858,10 @@ int tls_sw_recvmsg(struct sock *sk,
                if (err <= 0)
                        goto recv_end;
 
+               /* periodically flush backlog, and feed strparser */
+               tls_read_flush_backlog(sk, prot, len, to_decrypt,
+                                      decrypted + copied, &flushed_at);
+
                ctx->recv_pkt = NULL;
                __strp_unpause(&ctx->strp);
                __skb_queue_tail(&ctx->rx_list, skb);