@@ -2319,6 +2319,57 @@ static bool tcp_can_coalesce_send_queue_head(struct sock *sk, int len)
2319
2319
return true;
2320
2320
}
2321
2321
2322
+ static int tcp_clone_payload (struct sock * sk , struct sk_buff * to ,
2323
+ int probe_size )
2324
+ {
2325
+ skb_frag_t * lastfrag = NULL , * fragto = skb_shinfo (to )-> frags ;
2326
+ int i , todo , len = 0 , nr_frags = 0 ;
2327
+ const struct sk_buff * skb ;
2328
+
2329
+ if (!sk_wmem_schedule (sk , to -> truesize + probe_size ))
2330
+ return - ENOMEM ;
2331
+
2332
+ skb_queue_walk (& sk -> sk_write_queue , skb ) {
2333
+ const skb_frag_t * fragfrom = skb_shinfo (skb )-> frags ;
2334
+
2335
+ if (skb_headlen (skb ))
2336
+ return - EINVAL ;
2337
+
2338
+ for (i = 0 ; i < skb_shinfo (skb )-> nr_frags ; i ++ , fragfrom ++ ) {
2339
+ if (len >= probe_size )
2340
+ goto commit ;
2341
+ todo = min_t (int , skb_frag_size (fragfrom ),
2342
+ probe_size - len );
2343
+ len += todo ;
2344
+ if (lastfrag &&
2345
+ skb_frag_page (fragfrom ) == skb_frag_page (lastfrag ) &&
2346
+ skb_frag_off (fragfrom ) == skb_frag_off (lastfrag ) +
2347
+ skb_frag_size (lastfrag )) {
2348
+ skb_frag_size_add (lastfrag , todo );
2349
+ continue ;
2350
+ }
2351
+ if (unlikely (nr_frags == MAX_SKB_FRAGS ))
2352
+ return - E2BIG ;
2353
+ skb_frag_page_copy (fragto , fragfrom );
2354
+ skb_frag_off_copy (fragto , fragfrom );
2355
+ skb_frag_size_set (fragto , todo );
2356
+ nr_frags ++ ;
2357
+ lastfrag = fragto ++ ;
2358
+ }
2359
+ }
2360
+ commit :
2361
+ WARN_ON_ONCE (len != probe_size );
2362
+ for (i = 0 ; i < nr_frags ; i ++ )
2363
+ skb_frag_ref (to , i );
2364
+
2365
+ skb_shinfo (to )-> nr_frags = nr_frags ;
2366
+ to -> truesize += probe_size ;
2367
+ to -> len += probe_size ;
2368
+ to -> data_len += probe_size ;
2369
+ __skb_header_release (to );
2370
+ return 0 ;
2371
+ }
2372
+
2322
2373
/* Create a new MTU probe if we are ready.
2323
2374
* MTU probe is regularly attempting to increase the path MTU by
2324
2375
* deliberately sending larger packets. This discovers routing
@@ -2395,9 +2446,15 @@ static int tcp_mtu_probe(struct sock *sk)
2395
2446
return -1 ;
2396
2447
2397
2448
/* We're allowed to probe. Build it now. */
2398
- nskb = tcp_stream_alloc_skb (sk , probe_size , GFP_ATOMIC , false);
2449
+ nskb = tcp_stream_alloc_skb (sk , 0 , GFP_ATOMIC , false);
2399
2450
if (!nskb )
2400
2451
return -1 ;
2452
+
2453
+ /* build the payload, and be prepared to abort if this fails. */
2454
+ if (tcp_clone_payload (sk , nskb , probe_size )) {
2455
+ consume_skb (nskb );
2456
+ return -1 ;
2457
+ }
2401
2458
sk_wmem_queued_add (sk , nskb -> truesize );
2402
2459
sk_mem_charge (sk , nskb -> truesize );
2403
2460
@@ -2415,7 +2472,6 @@ static int tcp_mtu_probe(struct sock *sk)
2415
2472
len = 0 ;
2416
2473
tcp_for_write_queue_from_safe (skb , next , sk ) {
2417
2474
copy = min_t (int , skb -> len , probe_size - len );
2418
- skb_copy_bits (skb , 0 , skb_put (nskb , copy ), copy );
2419
2475
2420
2476
if (skb -> len <= copy ) {
2421
2477
/* We've eaten all the data from this skb.
0 commit comments