@@ -530,16 +530,22 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
530530 u32 off , u32 len ,
531531 struct sk_psock * psock ,
532532 struct sock * sk ,
533- struct sk_msg * msg )
533+ struct sk_msg * msg ,
534+ bool take_ref )
534535{
535536 int num_sge , copied ;
536537
538+ /* skb_to_sgvec will fail when the total number of fragments in
539+ * frag_list and frags exceeds MAX_MSG_FRAGS. For example, the
540+ * caller may aggregate multiple skbs.
541+ */
537542 num_sge = skb_to_sgvec (skb , msg -> sg .data , off , len );
538543 if (num_sge < 0 ) {
539544 /* skb linearize may fail with ENOMEM, but lets simply try again
540545 * later if this happens. Under memory pressure we don't want to
541546 * drop the skb. We need to linearize the skb so that the mapping
542547 * in skb_to_sgvec can not error.
548+ * Note that skb_linearize requires the skb not to be shared.
543549 */
544550 if (skb_linearize (skb ))
545551 return - EAGAIN ;
@@ -556,15 +562,15 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
556562 msg -> sg .start = 0 ;
557563 msg -> sg .size = copied ;
558564 msg -> sg .end = num_sge ;
559- msg -> skb = skb ;
565+ msg -> skb = take_ref ? skb_get ( skb ) : skb ;
560566
561567 sk_psock_queue_msg (psock , msg );
562568 sk_psock_data_ready (sk , psock );
563569 return copied ;
564570}
565571
566572static int sk_psock_skb_ingress_self (struct sk_psock * psock , struct sk_buff * skb ,
567- u32 off , u32 len );
573+ u32 off , u32 len , bool take_ref );
568574
569575static int sk_psock_skb_ingress (struct sk_psock * psock , struct sk_buff * skb ,
570576 u32 off , u32 len )
@@ -578,7 +584,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
578584 * correctly.
579585 */
580586 if (unlikely (skb -> sk == sk ))
581- return sk_psock_skb_ingress_self (psock , skb , off , len );
587+ return sk_psock_skb_ingress_self (psock , skb , off , len , true );
582588 msg = sk_psock_create_ingress_msg (sk , skb );
583589 if (!msg )
584590 return - EAGAIN ;
@@ -590,7 +596,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
590596 * into user buffers.
591597 */
592598 skb_set_owner_r (skb , sk );
593- err = sk_psock_skb_ingress_enqueue (skb , off , len , psock , sk , msg );
599+ err = sk_psock_skb_ingress_enqueue (skb , off , len , psock , sk , msg , true );
594600 if (err < 0 )
595601 kfree (msg );
596602 return err ;
@@ -601,7 +607,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
601607 * because the skb is already accounted for here.
602608 */
603609static int sk_psock_skb_ingress_self (struct sk_psock * psock , struct sk_buff * skb ,
604- u32 off , u32 len )
610+ u32 off , u32 len , bool take_ref )
605611{
606612 struct sk_msg * msg = alloc_sk_msg (GFP_ATOMIC );
607613 struct sock * sk = psock -> sk ;
@@ -610,7 +616,7 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb
610616 if (unlikely (!msg ))
611617 return - EAGAIN ;
612618 skb_set_owner_r (skb , sk );
613- err = sk_psock_skb_ingress_enqueue (skb , off , len , psock , sk , msg );
619+ err = sk_psock_skb_ingress_enqueue (skb , off , len , psock , sk , msg , take_ref );
614620 if (err < 0 )
615621 kfree (msg );
616622 return err ;
@@ -619,18 +625,13 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb
619625static int sk_psock_handle_skb (struct sk_psock * psock , struct sk_buff * skb ,
620626 u32 off , u32 len , bool ingress )
621627{
622- int err = 0 ;
623-
624628 if (!ingress ) {
625629 if (!sock_writeable (psock -> sk ))
626630 return - EAGAIN ;
627631 return skb_send_sock (psock -> sk , skb , off , len );
628632 }
629- skb_get (skb );
630- err = sk_psock_skb_ingress (psock , skb , off , len );
631- if (err < 0 )
632- kfree_skb (skb );
633- return err ;
633+
634+ return sk_psock_skb_ingress (psock , skb , off , len );
634635}
635636
636637static void sk_psock_skb_state (struct sk_psock * psock ,
@@ -1018,7 +1019,7 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb,
10181019 off = stm -> offset ;
10191020 len = stm -> full_len ;
10201021 }
1021- err = sk_psock_skb_ingress_self (psock , skb , off , len );
1022+ err = sk_psock_skb_ingress_self (psock , skb , off , len , false );
10221023 }
10231024 if (err < 0 ) {
10241025 spin_lock_bh (& psock -> ingress_lock );
0 commit comments