Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'splice-net-handle-msg_splice_pages-in-chelsio-tls'

David Howells says:

====================
splice, net: Handle MSG_SPLICE_PAGES in Chelsio-TLS

Here are patches to make Chelsio-TLS handle the MSG_SPLICE_PAGES internal
sendmsg flag. MSG_SPLICE_PAGES is an internal hint that tells the protocol
that it should splice the pages supplied if it can. Its sendpage
implementation is then turned into a wrapper around that.
====================

Link: https://lore.kernel.org/r/20230531110008.642903-1-dhowells@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+18 -103
+18 -103
drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_io.c
··· 1092 1092 if (copy > size) 1093 1093 copy = size; 1094 1094 1095 - if (skb_tailroom(skb) > 0) { 1095 + if (msg->msg_flags & MSG_SPLICE_PAGES) { 1096 + err = skb_splice_from_iter(skb, &msg->msg_iter, copy, 1097 + sk->sk_allocation); 1098 + if (err < 0) { 1099 + if (err == -EMSGSIZE) 1100 + goto new_buf; 1101 + goto do_fault; 1102 + } 1103 + copy = err; 1104 + sk_wmem_queued_add(sk, copy); 1105 + } else if (skb_tailroom(skb) > 0) { 1096 1106 copy = min(copy, skb_tailroom(skb)); 1097 1107 if (is_tls_tx(csk)) 1098 1108 copy = min_t(int, copy, csk->tlshws.txleft); ··· 1240 1230 int chtls_sendpage(struct sock *sk, struct page *page, 1241 1231 int offset, size_t size, int flags) 1242 1232 { 1243 - struct chtls_sock *csk; 1244 - struct chtls_dev *cdev; 1245 - int mss, err, copied; 1246 - struct tcp_sock *tp; 1247 - long timeo; 1233 + struct msghdr msg = { .msg_flags = flags | MSG_SPLICE_PAGES, }; 1234 + struct bio_vec bvec; 1248 1235 1249 - tp = tcp_sk(sk); 1250 - copied = 0; 1251 - csk = rcu_dereference_sk_user_data(sk); 1252 - cdev = csk->cdev; 1253 - lock_sock(sk); 1254 - timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); 1236 + if (flags & MSG_SENDPAGE_NOTLAST) 1237 + msg.msg_flags |= MSG_MORE; 1255 1238 1256 - err = sk_stream_wait_connect(sk, &timeo); 1257 - if (!sk_in_state(sk, TCPF_ESTABLISHED | TCPF_CLOSE_WAIT) && 1258 - err != 0) 1259 - goto out_err; 1260 - 1261 - mss = csk->mss; 1262 - csk_set_flag(csk, CSK_TX_MORE_DATA); 1263 - 1264 - while (size > 0) { 1265 - struct sk_buff *skb = skb_peek_tail(&csk->txq); 1266 - int copy, i; 1267 - 1268 - if (!skb || (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND) || 1269 - (copy = mss - skb->len) <= 0) { 1270 - new_buf: 1271 - if (!csk_mem_free(cdev, sk)) 1272 - goto wait_for_sndbuf; 1273 - 1274 - if (is_tls_tx(csk)) { 1275 - skb = get_record_skb(sk, 1276 - select_size(sk, size, 1277 - flags, 1278 - TX_TLSHDR_LEN), 1279 - true); 1280 - } else { 1281 - skb = get_tx_skb(sk, 0); 1282 - } 1283 - if (!skb) 1284 - goto wait_for_memory; 1285 - copy = mss; 1286 - } 1287 - if (copy > size) 1288 - copy = size; 1289 - 1290 - i = skb_shinfo(skb)->nr_frags; 1291 - if (skb_can_coalesce(skb, i, page, offset)) { 1292 - skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy); 1293 - } else if (i < MAX_SKB_FRAGS) { 1294 - get_page(page); 1295 - skb_fill_page_desc(skb, i, page, offset, copy); 1296 - } else { 1297 - tx_skb_finalize(skb); 1298 - push_frames_if_head(sk); 1299 - goto new_buf; 1300 - } 1301 - 1302 - skb->len += copy; 1303 - if (skb->len == mss) 1304 - tx_skb_finalize(skb); 1305 - skb->data_len += copy; 1306 - skb->truesize += copy; 1307 - sk->sk_wmem_queued += copy; 1308 - tp->write_seq += copy; 1309 - copied += copy; 1310 - offset += copy; 1311 - size -= copy; 1312 - 1313 - if (corked(tp, flags) && 1314 - (sk_stream_wspace(sk) < sk_stream_min_wspace(sk))) 1315 - ULP_SKB_CB(skb)->flags |= ULPCB_FLAG_NO_APPEND; 1316 - 1317 - if (!size) 1318 - break; 1319 - 1320 - if (unlikely(ULP_SKB_CB(skb)->flags & ULPCB_FLAG_NO_APPEND)) 1321 - push_frames_if_head(sk); 1322 - continue; 1323 - wait_for_sndbuf: 1324 - set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); 1325 - wait_for_memory: 1326 - err = csk_wait_memory(cdev, sk, &timeo); 1327 - if (err) 1328 - goto do_error; 1329 - } 1330 - out: 1331 - csk_reset_flag(csk, CSK_TX_MORE_DATA); 1332 - if (copied) 1333 - chtls_tcp_push(sk, flags); 1334 - done: 1335 - release_sock(sk); 1336 - return copied; 1337 - 1338 - do_error: 1339 - if (copied) 1340 - goto out; 1341 - 1342 - out_err: 1343 - if (csk_conn_inline(csk)) 1344 - csk_reset_flag(csk, CSK_TX_MORE_DATA); 1345 - copied = sk_stream_error(sk, flags, err); 1346 - goto done; 1239 + bvec_set_page(&bvec, page, size, offset); 1240 + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); 1241 + return chtls_sendmsg(sk, &msg, size); 1347 1242 } 1348 1243 1349 1244 static void chtls_select_window(struct sock *sk)