From: Alexander Duyck <hidden> Date: 2012-05-03 07:18:40
This set represents the original patch I had done for trying to cleanup
tcp_try_coalesce broken into 3 patches. The first one illustrates how I
believe we should be updating the truesize based on either the size of
sk_buff in the case of head reuse, or sk_buff plus the size of the head in
the case of a headlen of 0.
The other two patches go through and reorder things so there isn't as much
need for gotos. I believe it makes the code much more readable since it
starts at the top and finishes at the bottom instead of looping through the
entire code path a few times.
The last patch addresses an issue I ran into on ixgbe. It turns out the
recent HWMON patch added a but on 82598 adapters that caused the driver to
get hung in module unload. I figured I would submit it directly since it
is a small change to fix an issue that could have a larger impact.
On that note I am going to sleep now and will respond to any reviews and/or
comments in the morning.
---
Alexander Duyck (4):
ixgbe: Fix use after free on module remove
tcp: move stats merge to the end of tcp_try_coalesce
tcp: Move code related to head frag in tcp_try_coalesce
tcp: Fix truesize accounting in tcp_try_coalesce
drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c | 4 +
net/ipv4/tcp_input.c | 83 +++++++++++++-----------
2 files changed, 49 insertions(+), 38 deletions(-)
--
Thanks,
Alex
From: Alexander Duyck <hidden> Date: 2012-05-03 07:18:45
This patch addresses several issues in the way we were tracking the
truesize in tcp_try_coalesce.
First it was using ksize which prevents us from having a 0 sized head frag
and getting a usable result. To resolve that this patch uses the end
pointer which is set based off either ksize, or the frag_size supplied in
build_skb. This allows us to compute the original truesize of the entire
buffer and remove that value leaving us with just what was added as pages.
The second issue was the use of skb->len if there is a mergeable head frag.
We should only need to remove the size of an data aligned sk_buff from our
current skb->truesize to compute the delta for a buffer with a reused head.
By using skb->len the value of truesize was being artificially reduced
which means that head frags could use more memory than buffers using
standard allocations.
Signed-off-by: Alexander Duyck <redacted>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jeff Kirsher <redacted>
---
net/ipv4/tcp_input.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
@@ -4600,7 +4598,7 @@ copyfrags:skb_fill_page_desc(to,skb_shinfo(to)->nr_frags,page,offset,skb_headlen(from));*fragstolen=true;-delta=len;/* we dont know real truesize... */+delta=from->truesize-SKB_DATA_ALIGN(sizeof(structsk_buff));gotocopyfrags;}returnfalse;
From: Alexander Duyck <hidden> Date: 2012-05-03 07:18:58
This change reorders the code related to the use of an skb->head_frag so it
is placed before we check the rest of the frags. This allows the code to
read more linearly instead of like some sort of loop.
Signed-off-by: Alexander Duyck <redacted>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jeff Kirsher <redacted>
---
net/ipv4/tcp_input.c | 42 +++++++++++++++++++++++++-----------------
1 files changed, 25 insertions(+), 17 deletions(-)
From: Alexander Duyck <hidden> Date: 2012-05-03 07:19:01
While testing the TCP changes I had to fix an issue in order to be able to
load and unload the module.
The recent patch that added thermal sensor support added a use after free
bug on module unload with an 82598 adapter in the system. To resolve the
issue I have updated the code so that when we free the info_kobj we set it
back to NULL.
I suspect there are likely other bugs present, but I will leave that for
another patch that can undergo more testing.
I am submitting this directly to net-next since this fixes a fairly serious
bug that will lock up the ixgbe module until the system is rebooted.
Signed-off-by: Alexander Duyck <redacted>
Cc: Jeff Kirsher <redacted>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
From: Alexander Duyck <hidden> Date: 2012-05-03 07:19:16
This change cleans up the last bits of tcp_try_coalesce so that we only
need one goto which jumps to the end of the function. The idea is to make
the code more readable by putting things in a linear order so that we start
execution at the top of the function, and end it at the bottom.
I also made a slight tweak to the code for handling frags when we are a
clone. Instead of making it an if (clone) loop else nr_frags = 0 I changed
the logic so that if (!clone) we just set the number of frags to 0 which
disables the for loop anyway.
Signed-off-by: Alexander Duyck <redacted>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jeff Kirsher <redacted>
---
net/ipv4/tcp_input.c | 55 ++++++++++++++++++++++++++------------------------
1 files changed, 29 insertions(+), 26 deletions(-)
@@ -4589,27 +4586,33 @@ merge:delta=from->truesize-SKB_TRUESIZE(skb_end_pointer(from)-from->head);-copyfrags:-WARN_ON_ONCE(delta<len);-memcpy(skb_shinfo(to)->frags+skb_shinfo(to)->nr_frags,-skb_shinfo(from)->frags,-skb_shinfo(from)->nr_frags*sizeof(skb_frag_t));-skb_shinfo(to)->nr_frags+=skb_shinfo(from)->nr_frags;--if(skb_cloned(from))-for(i=0;i<skb_shinfo(from)->nr_frags;i++)-skb_frag_ref(from,i);-else-skb_shinfo(from)->nr_frags=0;--to->truesize+=delta;-atomic_add(delta,&sk->sk_rmem_alloc);-sk_mem_charge(sk,delta);-to->len+=len;-to->data_len+=len;-gotomerge;}-returnfalse;++WARN_ON_ONCE(delta<len);++memcpy(skb_shinfo(to)->frags+skb_shinfo(to)->nr_frags,+skb_shinfo(from)->frags,+skb_shinfo(from)->nr_frags*sizeof(skb_frag_t));+skb_shinfo(to)->nr_frags+=skb_shinfo(from)->nr_frags;++if(!skb_cloned(from))+skb_shinfo(from)->nr_frags=0;++/* if the skb is cloned this does nothing since we set nr_frags to 0 */+for(i=0;i<skb_shinfo(from)->nr_frags;i++)+skb_frag_ref(from,i);++to->truesize+=delta;+atomic_add(delta,&sk->sk_rmem_alloc);+sk_mem_charge(sk,delta);+to->len+=len;+to->data_len+=len;++merge:+NET_INC_STATS_BH(sock_net(sk),LINUX_MIB_TCPRCVCOALESCE);+TCP_SKB_CB(to)->end_seq=TCP_SKB_CB(from)->end_seq;+TCP_SKB_CB(to)->ack_seq=TCP_SKB_CB(from)->ack_seq;+returntrue;}staticvoidkfree_skb_partial(structsk_buff*skb,boolhead_stolen)
From: Eric Dumazet <hidden> Date: 2012-05-03 07:48:57
On Thu, 2012-05-03 at 00:18 -0700, Alexander Duyck wrote:
quoted hunk
This patch addresses several issues in the way we were tracking the
truesize in tcp_try_coalesce.
First it was using ksize which prevents us from having a 0 sized head frag
and getting a usable result. To resolve that this patch uses the end
pointer which is set based off either ksize, or the frag_size supplied in
build_skb. This allows us to compute the original truesize of the entire
buffer and remove that value leaving us with just what was added as pages.
The second issue was the use of skb->len if there is a mergeable head frag.
We should only need to remove the size of an data aligned sk_buff from our
current skb->truesize to compute the delta for a buffer with a reused head.
By using skb->len the value of truesize was being artificially reduced
which means that head frags could use more memory than buffers using
standard allocations.
Signed-off-by: Alexander Duyck <redacted>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jeff Kirsher <redacted>
---
net/ipv4/tcp_input.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
@@ -4600,7 +4598,7 @@ copyfrags:skb_fill_page_desc(to,skb_shinfo(to)->nr_frags,page,offset,skb_headlen(from));*fragstolen=true;-delta=len;/* we dont know real truesize... */+delta=from->truesize-SKB_DATA_ALIGN(sizeof(structsk_buff));gotocopyfrags;}returnfalse;--
From: Eric Dumazet <hidden> Date: 2012-05-03 07:50:59
On Thu, 2012-05-03 at 00:19 -0700, Alexander Duyck wrote:
This change reorders the code related to the use of an skb->head_frag so it
is placed before we check the rest of the frags. This allows the code to
read more linearly instead of like some sort of loop.
Signed-off-by: Alexander Duyck <redacted>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jeff Kirsher <redacted>
---
net/ipv4/tcp_input.c | 42 +++++++++++++++++++++++++-----------------
1 files changed, 25 insertions(+), 17 deletions(-)
From: Eric Dumazet <hidden> Date: 2012-05-03 07:52:48
On Thu, 2012-05-03 at 00:19 -0700, Alexander Duyck wrote:
This change cleans up the last bits of tcp_try_coalesce so that we only
need one goto which jumps to the end of the function. The idea is to make
the code more readable by putting things in a linear order so that we start
execution at the top of the function, and end it at the bottom.
I also made a slight tweak to the code for handling frags when we are a
clone. Instead of making it an if (clone) loop else nr_frags = 0 I changed
the logic so that if (!clone) we just set the number of frags to 0 which
disables the for loop anyway.
Signed-off-by: Alexander Duyck <redacted>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jeff Kirsher <redacted>
---
net/ipv4/tcp_input.c | 55 ++++++++++++++++++++++++++------------------------
1 files changed, 29 insertions(+), 26 deletions(-)
Thanks a lot Alex, this patch serie looks very good.
Acked-by: Eric Dumazet <edumazet@google.com>
From: David Miller <davem@davemloft.net> Date: 2012-05-03 08:22:05
From: Eric Dumazet <redacted>
Date: Thu, 03 May 2012 09:48:54 +0200
On Thu, 2012-05-03 at 00:18 -0700, Alexander Duyck wrote:
quoted
This patch addresses several issues in the way we were tracking the
truesize in tcp_try_coalesce.
First it was using ksize which prevents us from having a 0 sized head frag
and getting a usable result. To resolve that this patch uses the end
pointer which is set based off either ksize, or the frag_size supplied in
build_skb. This allows us to compute the original truesize of the entire
buffer and remove that value leaving us with just what was added as pages.
The second issue was the use of skb->len if there is a mergeable head frag.
We should only need to remove the size of an data aligned sk_buff from our
current skb->truesize to compute the delta for a buffer with a reused head.
By using skb->len the value of truesize was being artificially reduced
which means that head frags could use more memory than buffers using
standard allocations.
Signed-off-by: Alexander Duyck <redacted>
From: David Miller <davem@davemloft.net> Date: 2012-05-03 08:22:13
From: Eric Dumazet <redacted>
Date: Thu, 03 May 2012 09:50:56 +0200
On Thu, 2012-05-03 at 00:19 -0700, Alexander Duyck wrote:
quoted
This change reorders the code related to the use of an skb->head_frag so it
is placed before we check the rest of the frags. This allows the code to
read more linearly instead of like some sort of loop.
Signed-off-by: Alexander Duyck <redacted>
From: David Miller <davem@davemloft.net> Date: 2012-05-03 08:22:21
From: Eric Dumazet <redacted>
Date: Thu, 03 May 2012 09:52:45 +0200
On Thu, 2012-05-03 at 00:19 -0700, Alexander Duyck wrote:
quoted
This change cleans up the last bits of tcp_try_coalesce so that we only
need one goto which jumps to the end of the function. The idea is to make
the code more readable by putting things in a linear order so that we start
execution at the top of the function, and end it at the bottom.
I also made a slight tweak to the code for handling frags when we are a
clone. Instead of making it an if (clone) loop else nr_frags = 0 I changed
the logic so that if (!clone) we just set the number of frags to 0 which
disables the for loop anyway.
Signed-off-by: Alexander Duyck <redacted>
...
Thanks a lot Alex, this patch serie looks very good.
Acked-by: Eric Dumazet <edumazet@google.com>
From: David Miller <davem@davemloft.net> Date: 2012-05-03 08:22:30
From: Alexander Duyck <redacted>
Date: Thu, 03 May 2012 00:19:14 -0700
While testing the TCP changes I had to fix an issue in order to be able to
load and unload the module.
The recent patch that added thermal sensor support added a use after free
bug on module unload with an 82598 adapter in the system. To resolve the
issue I have updated the code so that when we free the info_kobj we set it
back to NULL.
I suspect there are likely other bugs present, but I will leave that for
another patch that can undergo more testing.
I am submitting this directly to net-next since this fixes a fairly serious
bug that will lock up the ixgbe module until the system is rebooted.
Signed-off-by: Alexander Duyck <redacted>
From: Eric Dumazet <hidden> Date: 2012-05-03 09:33:24
From: Eric Dumazet <edumazet@google.com>
GRO is very optimistic in skb truesize estimates, only taking into
account the used part of fragments.
Be conservative, and use more precise computation, so that bloated GRO
skbs can be collapsed eventually.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Alexander Duyck <redacted>
Cc: Jeff Kirsher <redacted>
---
net/core/skbuff.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
@@ -2929,6 +2933,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)memcpy(frag+1,skbinfo->frags,sizeof(*frag)*skbinfo->nr_frags);/* We dont need to clear skbinfo->nr_frags here */+delta_truesize=skb->truesize-SKB_DATA_ALIGN(sizeof(structsk_buff));NAPI_GRO_CB(skb)->free=NAPI_GRO_FREE_STOLEN_HEAD;gotodone;}elseif(skb_gro_len(p)!=pinfo->gso_size)
From: Alexander Duyck <hidden> Date: 2012-05-03 10:43:58
On 05/03/2012 02:33 AM, Eric Dumazet wrote:
quoted hunk
From: Eric Dumazet<edumazet@google.com>
GRO is very optimistic in skb truesize estimates, only taking into
account the used part of fragments.
Be conservative, and use more precise computation, so that bloated GRO
skbs can be collapsed eventually.
Signed-off-by: Eric Dumazet<edumazet@google.com>
Cc: Alexander Duyck<redacted>
Cc: Jeff Kirsher<redacted>
---
net/core/skbuff.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
@@ -2929,6 +2933,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)memcpy(frag+1,skbinfo->frags,sizeof(*frag)*skbinfo->nr_frags);/* We dont need to clear skbinfo->nr_frags here */+delta_truesize=skb->truesize-SKB_DATA_ALIGN(sizeof(structsk_buff));NAPI_GRO_CB(skb)->free=NAPI_GRO_FREE_STOLEN_HEAD;gotodone;}elseif(skb_gro_len(p)!=pinfo->gso_size)
Couldn't sleep so I figured I would review some patches and maybe get a
few more written before the sun came up. I was actually thinking of
trying to get to this before I logged in. Looks like you have this one
taken care of already so I will go take care of skb_head_is_locked.
Acked-by: Alexander Duyck <redacted>
From: David Miller <davem@davemloft.net> Date: 2012-05-03 17:22:52
From: Eric Dumazet <redacted>
Date: Thu, 03 May 2012 11:33:21 +0200
From: Eric Dumazet <edumazet@google.com>
GRO is very optimistic in skb truesize estimates, only taking into
account the used part of fragments.
Be conservative, and use more precise computation, so that bloated GRO
skbs can be collapsed eventually.
Signed-off-by: Eric Dumazet <edumazet@google.com>