diff mbox series

[net-next,01/19] net: tcp: introduce tcp_drop_reason()

Message ID 20220215112812.2093852-2-imagedong@tencent.com (mailing list archive)
State Not Applicable
Delegated to: Netdev Maintainers
Headers show
Series net: add skb drop reasons for TCP, IP, dev and neigh | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/apply fail Patch does not apply to net-next

Commit Message

Menglong Dong Feb. 15, 2022, 11:27 a.m. UTC
From: Menglong Dong <imagedong@tencent.com>

For TCP protocol, tcp_drop() is used to free the skb when it needs
to be dropped. To make use of kfree_skb_reason() and collect drop
reasons, introduce the function tcp_drop_reason().

tcp_drop_reason() will finally call kfree_skb_reason() and pass the
drop reason to 'kfree_skb' tracepoint.

PS: __kfree_skb() was used in tcp_drop(), I'm not sure if it's ok
to replace it with kfree_skb_reason().

Signed-off-by: Menglong Dong <imagedong@tencent.com>
---
 net/ipv4/tcp_input.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

Comments

Eric Dumazet Feb. 15, 2022, 5:34 p.m. UTC | #1
On Tue, Feb 15, 2022 at 3:30 AM <menglong8.dong@gmail.com> wrote:
>
> From: Menglong Dong <imagedong@tencent.com>
>
> For TCP protocol, tcp_drop() is used to free the skb when it needs
> to be dropped. To make use of kfree_skb_reason() and collect drop
> reasons, introduce the function tcp_drop_reason().
>
> tcp_drop_reason() will finally call kfree_skb_reason() and pass the
> drop reason to 'kfree_skb' tracepoint.
>
> PS: __kfree_skb() was used in tcp_drop(), I'm not sure if it's ok
> to replace it with kfree_skb_reason().
>
> Signed-off-by: Menglong Dong <imagedong@tencent.com>
> ---
>  net/ipv4/tcp_input.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> index af94a6d22a9d..e3811afd1756 100644
> --- a/net/ipv4/tcp_input.c
> +++ b/net/ipv4/tcp_input.c
> @@ -4684,10 +4684,19 @@ static bool tcp_ooo_try_coalesce(struct sock *sk,
>         return res;
>  }
>
> -static void tcp_drop(struct sock *sk, struct sk_buff *skb)
> +static void tcp_drop_reason(struct sock *sk, struct sk_buff *skb,
> +                           enum skb_drop_reason reason)
>  {
>         sk_drops_add(sk, skb);
> -       __kfree_skb(skb);
> +       /* why __kfree_skb() used here before, other than kfree_skb()?
> +        * confusing......

Do not add comments like that if you do not know the difference...

__kfree_skb() is used by TCP stack because it owns skb in receive
queues, and avoids touching skb->users
because it must be one already.

(We made sure not using skb_get() in TCP)

It seems fine to use kfree_skb() in tcp_drop(), it is hardly fast
path, and the added cost is pure noise.
David Ahern Feb. 15, 2022, 6:47 p.m. UTC | #2
On 2/15/22 10:34 AM, Eric Dumazet wrote:
>> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
>> index af94a6d22a9d..e3811afd1756 100644
>> --- a/net/ipv4/tcp_input.c
>> +++ b/net/ipv4/tcp_input.c
>> @@ -4684,10 +4684,19 @@ static bool tcp_ooo_try_coalesce(struct sock *sk,
>>         return res;
>>  }
>>
>> -static void tcp_drop(struct sock *sk, struct sk_buff *skb)
>> +static void tcp_drop_reason(struct sock *sk, struct sk_buff *skb,
>> +                           enum skb_drop_reason reason)
>>  {
>>         sk_drops_add(sk, skb);
>> -       __kfree_skb(skb);
>> +       /* why __kfree_skb() used here before, other than kfree_skb()?
>> +        * confusing......
> 
> Do not add comments like that if you do not know the difference...
> 
> __kfree_skb() is used by TCP stack because it owns skb in receive
> queues, and avoids touching skb->users
> because it must be one already.

and it bypasses kfree_skb tracepoint which seems by design.
Menglong Dong Feb. 16, 2022, 2:31 a.m. UTC | #3
On Wed, Feb 16, 2022 at 1:34 AM Eric Dumazet <edumazet@google.com> wrote:
>
> On Tue, Feb 15, 2022 at 3:30 AM <menglong8.dong@gmail.com> wrote:
> >
> > From: Menglong Dong <imagedong@tencent.com>
> >
> > For TCP protocol, tcp_drop() is used to free the skb when it needs
> > to be dropped. To make use of kfree_skb_reason() and collect drop
> > reasons, introduce the function tcp_drop_reason().
> >
> > tcp_drop_reason() will finally call kfree_skb_reason() and pass the
> > drop reason to 'kfree_skb' tracepoint.
> >
> > PS: __kfree_skb() was used in tcp_drop(), I'm not sure if it's ok
> > to replace it with kfree_skb_reason().
> >
> > Signed-off-by: Menglong Dong <imagedong@tencent.com>
> > ---
> >  net/ipv4/tcp_input.c | 13 +++++++++++--
> >  1 file changed, 11 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> > index af94a6d22a9d..e3811afd1756 100644
> > --- a/net/ipv4/tcp_input.c
> > +++ b/net/ipv4/tcp_input.c
> > @@ -4684,10 +4684,19 @@ static bool tcp_ooo_try_coalesce(struct sock *sk,
> >         return res;
> >  }
> >
> > -static void tcp_drop(struct sock *sk, struct sk_buff *skb)
> > +static void tcp_drop_reason(struct sock *sk, struct sk_buff *skb,
> > +                           enum skb_drop_reason reason)
> >  {
> >         sk_drops_add(sk, skb);
> > -       __kfree_skb(skb);
> > +       /* why __kfree_skb() used here before, other than kfree_skb()?
> > +        * confusing......
>
> Do not add comments like that if you do not know the difference...
>
> __kfree_skb() is used by TCP stack because it owns skb in receive
> queues, and avoids touching skb->users
> because it must be one already.
>
> (We made sure not using skb_get() in TCP)
>
> It seems fine to use kfree_skb() in tcp_drop(), it is hardly fast
> path, and the added cost is pure noise.

I understand why __kfree_skb() was used now, and it seems
this commit is ok (with the comments removed of course). I'll
keep it still.

Thanks!
Menglong Dong
Menglong Dong Feb. 16, 2022, 2:38 a.m. UTC | #4
On Wed, Feb 16, 2022 at 2:47 AM David Ahern <dsahern@kernel.org> wrote:
>
> On 2/15/22 10:34 AM, Eric Dumazet wrote:
> >> diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
> >> index af94a6d22a9d..e3811afd1756 100644
> >> --- a/net/ipv4/tcp_input.c
> >> +++ b/net/ipv4/tcp_input.c
> >> @@ -4684,10 +4684,19 @@ static bool tcp_ooo_try_coalesce(struct sock *sk,
> >>         return res;
> >>  }
> >>
> >> -static void tcp_drop(struct sock *sk, struct sk_buff *skb)
> >> +static void tcp_drop_reason(struct sock *sk, struct sk_buff *skb,
> >> +                           enum skb_drop_reason reason)
> >>  {
> >>         sk_drops_add(sk, skb);
> >> -       __kfree_skb(skb);
> >> +       /* why __kfree_skb() used here before, other than kfree_skb()?
> >> +        * confusing......
> >
> > Do not add comments like that if you do not know the difference...
> >
> > __kfree_skb() is used by TCP stack because it owns skb in receive
> > queues, and avoids touching skb->users
> > because it must be one already.
>
> and it bypasses kfree_skb tracepoint which seems by design.

Do you mean it shouldn't be traced here?
According to my understanding, __kfree_skb() was used in the
beginning as skb->users aren't touched by TCP. Later,
tcp_drop() was introduced to record drop count to the socket.

Considering the skb is indeed dropped and no other event is triggered,
is it ok to trigger the kfree_skb tracepoint?

Thanks!
Menglong Dong
diff mbox series

Patch

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index af94a6d22a9d..e3811afd1756 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4684,10 +4684,19 @@  static bool tcp_ooo_try_coalesce(struct sock *sk,
 	return res;
 }
 
-static void tcp_drop(struct sock *sk, struct sk_buff *skb)
+static void tcp_drop_reason(struct sock *sk, struct sk_buff *skb,
+			    enum skb_drop_reason reason)
 {
 	sk_drops_add(sk, skb);
-	__kfree_skb(skb);
+	/* why __kfree_skb() used here before, other than kfree_skb()?
+	 * confusing......
+	 */
+	kfree_skb_reason(skb, reason);
+}
+
+static inline void tcp_drop(struct sock *sk, struct sk_buff *skb)
+{
+	tcp_drop_reason(sk, skb, SKB_DROP_REASON_NOT_SPECIFIED);
 }
 
 /* This one checks to see if we can put data from the