@@ -529,16 +529,22 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
529
529
u32 off , u32 len ,
530
530
struct sk_psock * psock ,
531
531
struct sock * sk ,
532
- struct sk_msg * msg )
532
+ struct sk_msg * msg ,
533
+ bool take_ref )
533
534
{
534
535
int num_sge , copied ;
535
536
537
+ /* skb_to_sgvec will fail when the total number of fragments in
538
+ * frag_list and frags exceeds MAX_MSG_FRAGS. For example, the
539
+ * caller may aggregate multiple skbs.
540
+ */
536
541
num_sge = skb_to_sgvec (skb , msg -> sg .data , off , len );
537
542
if (num_sge < 0 ) {
538
543
/* skb linearize may fail with ENOMEM, but lets simply try again
539
544
* later if this happens. Under memory pressure we don't want to
540
545
* drop the skb. We need to linearize the skb so that the mapping
541
546
* in skb_to_sgvec can not error.
547
+ * Note that skb_linearize requires the skb not to be shared.
542
548
*/
543
549
if (skb_linearize (skb ))
544
550
return - EAGAIN ;
@@ -555,15 +561,15 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
555
561
msg -> sg .start = 0 ;
556
562
msg -> sg .size = copied ;
557
563
msg -> sg .end = num_sge ;
558
- msg -> skb = skb ;
564
+ msg -> skb = take_ref ? skb_get ( skb ) : skb ;
559
565
560
566
sk_psock_queue_msg (psock , msg );
561
567
sk_psock_data_ready (sk , psock );
562
568
return copied ;
563
569
}
564
570
565
571
static int sk_psock_skb_ingress_self (struct sk_psock * psock , struct sk_buff * skb ,
566
- u32 off , u32 len );
572
+ u32 off , u32 len , bool take_ref );
567
573
568
574
static int sk_psock_skb_ingress (struct sk_psock * psock , struct sk_buff * skb ,
569
575
u32 off , u32 len )
@@ -577,7 +583,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
577
583
* correctly.
578
584
*/
579
585
if (unlikely (skb -> sk == sk ))
580
- return sk_psock_skb_ingress_self (psock , skb , off , len );
586
+ return sk_psock_skb_ingress_self (psock , skb , off , len , true );
581
587
msg = sk_psock_create_ingress_msg (sk , skb );
582
588
if (!msg )
583
589
return - EAGAIN ;
@@ -589,7 +595,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
589
595
* into user buffers.
590
596
*/
591
597
skb_set_owner_r (skb , sk );
592
- err = sk_psock_skb_ingress_enqueue (skb , off , len , psock , sk , msg );
598
+ err = sk_psock_skb_ingress_enqueue (skb , off , len , psock , sk , msg , true );
593
599
if (err < 0 )
594
600
kfree (msg );
595
601
return err ;
@@ -600,7 +606,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
600
606
* because the skb is already accounted for here.
601
607
*/
602
608
static int sk_psock_skb_ingress_self (struct sk_psock * psock , struct sk_buff * skb ,
603
- u32 off , u32 len )
609
+ u32 off , u32 len , bool take_ref )
604
610
{
605
611
struct sk_msg * msg = alloc_sk_msg (GFP_ATOMIC );
606
612
struct sock * sk = psock -> sk ;
@@ -609,7 +615,7 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb
609
615
if (unlikely (!msg ))
610
616
return - EAGAIN ;
611
617
skb_set_owner_r (skb , sk );
612
- err = sk_psock_skb_ingress_enqueue (skb , off , len , psock , sk , msg );
618
+ err = sk_psock_skb_ingress_enqueue (skb , off , len , psock , sk , msg , take_ref );
613
619
if (err < 0 )
614
620
kfree (msg );
615
621
return err ;
@@ -618,18 +624,13 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb
618
624
static int sk_psock_handle_skb (struct sk_psock * psock , struct sk_buff * skb ,
619
625
u32 off , u32 len , bool ingress )
620
626
{
621
- int err = 0 ;
622
-
623
627
if (!ingress ) {
624
628
if (!sock_writeable (psock -> sk ))
625
629
return - EAGAIN ;
626
630
return skb_send_sock (psock -> sk , skb , off , len );
627
631
}
628
- skb_get (skb );
629
- err = sk_psock_skb_ingress (psock , skb , off , len );
630
- if (err < 0 )
631
- kfree_skb (skb );
632
- return err ;
632
+
633
+ return sk_psock_skb_ingress (psock , skb , off , len );
633
634
}
634
635
635
636
static void sk_psock_skb_state (struct sk_psock * psock ,
@@ -1017,7 +1018,7 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb,
1017
1018
off = stm -> offset ;
1018
1019
len = stm -> full_len ;
1019
1020
}
1020
- err = sk_psock_skb_ingress_self (psock , skb , off , len );
1021
+ err = sk_psock_skb_ingress_self (psock , skb , off , len , false );
1021
1022
}
1022
1023
if (err < 0 ) {
1023
1024
spin_lock_bh (& psock -> ingress_lock );
0 commit comments