Skip to content

Commit 84c61fe

Browse files
committed
tls: rx: do not use the standard strparser
TLS is a relatively poor fit for strparser. We pause the input every time a message is received, wait for a read which will decrypt the message, start the parser, repeat. strparser is built to delineate the messages, wrap them in individual skbs and let them float off into the stack or a different socket. TLS wants the data pages and nothing else. There's no need for TLS to keep cloning (and occasionally skb_unclone()'ing) the TCP rx queue. This patch uses a pre-allocated skb and attaches the skbs from the TCP rx queue to it as frags. TLS is careful never to modify the input skb without CoW'ing / detaching it first. Since we call TCP rx queue cleanup directly we also get back the benefit of skb deferred free. Overall this results in a 6% gain in my benchmarks. Acked-by: Paolo Abeni <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 8b3c59a commit 84c61fe

File tree

5 files changed

+558
-69
lines changed

5 files changed

+558
-69
lines changed

include/net/tls.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,18 +108,33 @@ struct tls_sw_context_tx {
108108
unsigned long tx_bitmask;
109109
};
110110

111+
struct tls_strparser {
112+
struct sock *sk;
113+
114+
u32 mark : 8;
115+
u32 stopped : 1;
116+
u32 copy_mode : 1;
117+
u32 msg_ready : 1;
118+
119+
struct strp_msg stm;
120+
121+
struct sk_buff *anchor;
122+
struct work_struct work;
123+
};
124+
111125
struct tls_sw_context_rx {
112126
struct crypto_aead *aead_recv;
113127
struct crypto_wait async_wait;
114-
struct strparser strp;
115128
struct sk_buff_head rx_list; /* list of decrypted 'data' records */
116129
void (*saved_data_ready)(struct sock *sk);
117130

118-
struct sk_buff *recv_pkt;
119131
u8 reader_present;
120132
u8 async_capable:1;
121133
u8 zc_capable:1;
122134
u8 reader_contended:1;
135+
136+
struct tls_strparser strp;
137+
123138
atomic_t decrypt_pending;
124139
/* protect crypto_wait with decrypt_pending*/
125140
spinlock_t decrypt_compl_lock;

net/tls/tls.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* Copyright (c) 2016 Tom Herbert <[email protected]>
23
* Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved.
34
* Copyright (c) 2016-2017, Dave Watson <[email protected]>. All rights reserved.
45
*
@@ -127,10 +128,24 @@ int tls_sw_fallback_init(struct sock *sk,
127128
struct tls_offload_context_tx *offload_ctx,
128129
struct tls_crypto_info *crypto_info);
129130

131+
int tls_strp_dev_init(void);
132+
void tls_strp_dev_exit(void);
133+
134+
void tls_strp_done(struct tls_strparser *strp);
135+
void tls_strp_stop(struct tls_strparser *strp);
136+
int tls_strp_init(struct tls_strparser *strp, struct sock *sk);
137+
void tls_strp_data_ready(struct tls_strparser *strp);
138+
139+
void tls_strp_check_rcv(struct tls_strparser *strp);
140+
void tls_strp_msg_done(struct tls_strparser *strp);
141+
142+
int tls_rx_msg_size(struct tls_strparser *strp, struct sk_buff *skb);
143+
void tls_rx_msg_ready(struct tls_strparser *strp);
144+
145+
void tls_strp_msg_load(struct tls_strparser *strp, bool force_refresh);
130146
int tls_strp_msg_cow(struct tls_sw_context_rx *ctx);
131147
struct sk_buff *tls_strp_msg_detach(struct tls_sw_context_rx *ctx);
132-
int tls_strp_msg_hold(struct sock *sk, struct sk_buff *skb,
133-
struct sk_buff_head *dst);
148+
int tls_strp_msg_hold(struct tls_strparser *strp, struct sk_buff_head *dst);
134149

135150
static inline struct tls_msg *tls_msg(struct sk_buff *skb)
136151
{
@@ -141,12 +156,13 @@ static inline struct tls_msg *tls_msg(struct sk_buff *skb)
141156

142157
static inline struct sk_buff *tls_strp_msg(struct tls_sw_context_rx *ctx)
143158
{
144-
return ctx->recv_pkt;
159+
DEBUG_NET_WARN_ON_ONCE(!ctx->strp.msg_ready || !ctx->strp.anchor->len);
160+
return ctx->strp.anchor;
145161
}
146162

147163
static inline bool tls_strp_msg_ready(struct tls_sw_context_rx *ctx)
148164
{
149-
return ctx->recv_pkt;
165+
return ctx->strp.msg_ready;
150166
}
151167

152168
#ifdef CONFIG_TLS_DEVICE

net/tls/tls_main.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,10 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
725725
if (tx) {
726726
ctx->sk_write_space = sk->sk_write_space;
727727
sk->sk_write_space = tls_write_space;
728+
} else {
729+
struct tls_sw_context_rx *rx_ctx = tls_sw_ctx_rx(ctx);
730+
731+
tls_strp_check_rcv(&rx_ctx->strp);
728732
}
729733
return 0;
730734

@@ -1141,20 +1145,28 @@ static int __init tls_register(void)
11411145
if (err)
11421146
return err;
11431147

1148+
err = tls_strp_dev_init();
1149+
if (err)
1150+
goto err_pernet;
1151+
11441152
err = tls_device_init();
1145-
if (err) {
1146-
unregister_pernet_subsys(&tls_proc_ops);
1147-
return err;
1148-
}
1153+
if (err)
1154+
goto err_strp;
11491155

11501156
tcp_register_ulp(&tcp_tls_ulp_ops);
11511157

11521158
return 0;
1159+
err_strp:
1160+
tls_strp_dev_exit();
1161+
err_pernet:
1162+
unregister_pernet_subsys(&tls_proc_ops);
1163+
return err;
11531164
}
11541165

11551166
static void __exit tls_unregister(void)
11561167
{
11571168
tcp_unregister_ulp(&tcp_tls_ulp_ops);
1169+
tls_strp_dev_exit();
11581170
tls_device_cleanup();
11591171
unregister_pernet_subsys(&tls_proc_ops);
11601172
}

0 commit comments

Comments
 (0)