[INET]: Fix truesize setting in ip_append_data

Previous thread: Re: [PATCH 06/26] atl1: update initialization parameters by Jay Cliburn on Tuesday, January 22, 2008 - 10:13 pm. (3 messages)

Next thread: [Bug 9750] [patch 2.6.24] dev: avoid a race that triggers assertion failure by Matti Linnanvuori on Wednesday, January 23, 2008 - 2:34 am. (1 message)
To: David S. Miller <davem@...>, <netdev@...>
Date: Tuesday, January 22, 2008 - 11:39 pm

Hi Dave:

[INET]: Fix truesize setting in ip_append_data

As it is ip_append_data only counts page fragments to the skb that
allocated it. As such it means that the first skb gets hit with a
4K charge even though it might have only used a fraction of it while
all subsequent skb's that use the same page gets away with no charge
at all.

This bug was exposed by the UDP accounting patch.

This patch also fixes a similar bug in ip_append_page spotted by you :)

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index fd99fbd..df1eff1 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1016,7 +1016,6 @@ alloc_new_skb:

skb_fill_page_desc(skb, i, page, 0, 0);
frag = &skb_shinfo(skb)->frags[i];
- skb->truesize += PAGE_SIZE;
atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
} else {
err = -EMSGSIZE;
@@ -1030,6 +1029,7 @@ alloc_new_skb:
frag->size += copy;
skb->len += copy;
skb->data_len += copy;
+ skb->truesize += copy;
}
offset += copy;
length -= copy;
@@ -1172,6 +1172,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,

skb->len += len;
skb->data_len += len;
+ skb->truesize += len;
offset += len;
size -= len;
}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 6338a9c..bb6ba1e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1316,7 +1316,6 @@ alloc_new_skb:

skb_fill_page_desc(skb, i, page, 0, 0);
frag = &skb_shinfo(skb)->frags[i];
- skb->truesize += PAGE_SIZE;
atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
} else {
err = -EMSGSIZE;
@@ -1330,6 +1329,7 @@ alloc_new_skb:
...

To: <herbert@...>
Cc: <netdev@...>
Date: Wednesday, January 23, 2008 - 1:47 am

From: Herbert Xu <herbert@gondor.apana.org.au>

I added this to net-2.6, thanks Herbert!

I already checked in the ip_append_page() fix to net-2.6 so
I simply removed that hunk when adding your fix.

Thanks again!
--

To: David Miller <davem@...>
Cc: <netdev@...>
Date: Wednesday, January 23, 2008 - 2:41 am

Thank you!

I just received a message from Takahiro Yasui that my bug fix is buggy
too :) So here is a fix on top of that.

[INET]: Change sk_wmem_alloc together with truesize

Whenever truesize gets updated on output we need to update sk_wmem_alloc
too because when the packet gets freed the truesize will be subtracted
from it. This patch fixes the out-of-place sk_wmem_alloc in ip_append_data
and ip_append_page.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index df1eff1..bc9e575 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1016,7 +1016,6 @@ alloc_new_skb:

skb_fill_page_desc(skb, i, page, 0, 0);
frag = &skb_shinfo(skb)->frags[i];
- atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
} else {
err = -EMSGSIZE;
goto error;
@@ -1030,6 +1029,7 @@ alloc_new_skb:
skb->len += copy;
skb->data_len += copy;
skb->truesize += copy;
+ atomic_add(copy, &sk->sk_wmem_alloc);
}
offset += copy;
length -= copy;
@@ -1173,6 +1173,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
skb->len += len;
skb->data_len += len;
skb->truesize += len;
+ atomic_add(len, &sk->sk_wmem_alloc);
offset += len;
size -= len;
}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index bb6ba1e..3bef30e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1316,7 +1316,6 @@ alloc_new_skb:

skb_fill_page_desc(skb, i, page, 0, 0);
frag = &skb_shinfo(skb)->frags[i];
- atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
} else {
err = -EMSGSIZE;
goto error;
@@ -1330,6 +1329,7 @@ alloc_new_skb:
skb->len...

To: <herbert@...>
Cc: <netdev@...>
Date: Wednesday, January 23, 2008 - 2:43 am

From: Herbert Xu <herbert@gondor.apana.org.au>

I already correct this and respinned the net-2.6 tree
--

Previous thread: Re: [PATCH 06/26] atl1: update initialization parameters by Jay Cliburn on Tuesday, January 22, 2008 - 10:13 pm. (3 messages)

Next thread: [Bug 9750] [patch 2.6.24] dev: avoid a race that triggers assertion failure by Matti Linnanvuori on Wednesday, January 23, 2008 - 2:34 am. (1 message)