[SK_BUFF]: Convert skb->tail to sk_buff_data_t
So that it is also an offset from skb->head, reduces its size from 8 to 4 bytes
on 64bit architectures, allowing us to combine the 4 bytes hole left by the
layer headers conversion, reducing struct sk_buff size to 256 bytes, i.e. 4
64byte cachelines, and since the sk_buff slab cache is SLAB_HWCACHE_ALIGN...
:-)
Many calculations that previously required that skb->{transport,network,
mac}_header be first converted to a pointer now can be done directly, being
meaningful as offsets or pointers.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/core/dev.c b/net/core/dev.c
index 6562e57..86dc9f6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1069,7 +1069,7 @@
skb_reset_mac_header(skb2);
if (skb_network_header(skb2) < skb2->data ||
- skb_network_header(skb2) > skb2->tail) {
+ skb2->network_header > skb2->tail) {
if (net_ratelimit())
printk(KERN_CRIT "protocol %04x is "
"buggy, dev %s\n",
@@ -1175,7 +1175,7 @@
BUG_ON(offset > (int)skb->len);
csum = skb_checksum(skb, offset, skb->len-offset, 0);
- offset = skb->tail - skb_transport_header(skb);
+ offset = skb->tail - skb->transport_header;
BUG_ON(offset <= 0);
BUG_ON(skb->csum_offset + 2 > offset);
diff --git a/net/core/filter.c b/net/core/filter.c
index d2358a5..bd903aa 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -46,7 +46,7 @@
else if (k >= SKF_LL_OFF)
ptr = skb_mac_header(skb) + k - SKF_LL_OFF;
- if (ptr >= skb->head && ptr < skb->tail)
+ if (ptr >= skb->head && ptr < skb_tail_pointer(skb))
return ptr;
return NULL;
}
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c
index 259473d..bcc2559 100644
--- a/net/core/gen_stats.c
+++ b/net/core/gen_stats.c
@@ -61,7 +61,7 @@
spin_lock_bh(lock);
d->lock = lock;
if (type)
- d->tail = (struct rtattr *) skb->tail;
+ d->tail = (struct rtattr *)skb_tail_pointer(skb);
d->skb = skb;
d->compat_tc_stats = tc_stats_type;
d->compat_xstats = xstats_type;
@@ -212,7 +212,7 @@
gnet_stats_finish_copy(struct gnet_dump *d)
{
if (d->tail)
- d->tail->rta_len = d->skb->tail - (u8 *) d->tail;
+ d->tail->rta_len = skb_tail_pointer(d->skb) - (u8 *)d->tail;
if (d->compat_tc_stats)
if (gnet_stats_copy(d, d->compat_tc_stats, &d->tc_stats,
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 9da8357..f9469ea 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2357,7 +2357,7 @@
*vlan_encapsulated_proto = htons(ETH_P_IP);
}
- skb_set_network_header(skb, skb->tail - skb->data);
+ skb->network_header = skb->tail;
skb->transport_header = skb->network_header + sizeof(struct iphdr);
skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr));
@@ -2696,7 +2696,7 @@
*vlan_encapsulated_proto = htons(ETH_P_IPV6);
}
- skb_set_network_header(skb, skb->tail - skb->data);
+ skb->network_header = skb->tail;
skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr));
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index a48b086..ddcbc4d 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -87,8 +87,9 @@
void skb_over_panic(struct sk_buff *skb, int sz, void *here)
{
printk(KERN_EMERG "skb_over_panic: text:%p len:%d put:%d head:%p "
- "data:%p tail:%p end:%p dev:%s\n",
- here, skb->len, sz, skb->head, skb->data, skb->tail, skb->end,
+ "data:%p tail:%#lx end:%p dev:%s\n",
+ here, skb->len, sz, skb->head, skb->data,
+ (unsigned long)skb->tail, skb->end,
skb->dev ? skb->dev->name : "<NULL>");
BUG();
}
@@ -105,8 +106,9 @@
void skb_under_panic(struct sk_buff *skb, int sz, void *here)
{
printk(KERN_EMERG "skb_under_panic: text:%p len:%d put:%d head:%p "
- "data:%p tail:%p end:%p dev:%s\n",
- here, skb->len, sz, skb->head, skb->data, skb->tail, skb->end,
+ "data:%p tail:%#lx end:%p dev:%s\n",
+ here, skb->len, sz, skb->head, skb->data,
+ (unsigned long)skb->tail, skb->end,
skb->dev ? skb->dev->name : "<NULL>");
BUG();
}
@@ -167,7 +169,7 @@
atomic_set(&skb->users, 1);
skb->head = data;
skb->data = data;
- skb->tail = data;
+ skb_reset_tail_pointer(skb);
skb->end = data + size;
/* make sure we initialize shinfo sequentially */
shinfo = skb_shinfo(skb);
@@ -629,7 +631,12 @@
/* Copy only real data... and, alas, header. This should be
* optimized for the cases when header is void. */
- memcpy(data + nhead, skb->head, skb->tail - skb->head);
+ memcpy(data + nhead, skb->head,
+ skb->tail
+#ifndef NET_SKBUFF_DATA_USES_OFFSET
+ - skb->head
+#endif
+ );
memcpy(data + size, skb->end, sizeof(struct skb_shared_info));
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
@@ -645,9 +652,9 @@
skb->head = data;
skb->end = data + size;
skb->data += off;
- skb->tail += off;
#ifndef NET_SKBUFF_DATA_USES_OFFSET
- /* {transport,network,mac}_header are relative to skb->head */
+ /* {transport,network,mac}_header and tail are relative to skb->head */
+ skb->tail += off;
skb->transport_header += off;
skb->network_header += off;
skb->mac_header += off;
@@ -762,7 +769,7 @@
return 0;
}
- ntail = skb->data_len + pad - (skb->end - skb->tail);
+ ntail = skb->data_len + pad - (skb->end - skb_tail_pointer(skb));
if (likely(skb_cloned(skb) || ntail > 0)) {
err = pskb_expand_head(skb, 0, ntail, GFP_ATOMIC);
if (unlikely(err))
@@ -863,7 +870,7 @@
} else {
skb->len = len;
skb->data_len = 0;
- skb->tail = skb->data + len;
+ skb_set_tail_pointer(skb, len);
}
return 0;
@@ -900,7 +907,7 @@
* plus 128 bytes for future expansions. If we have enough
* room at tail, reallocate without expansion only if skb is cloned.
*/
- int i, k, eat = (skb->tail + delta) - skb->end;
+ int i, k, eat = (skb_tail_pointer(skb) + delta) - skb->end;
if (eat > 0 || skb_cloned(skb)) {
if (pskb_expand_head(skb, 0, eat > 0 ? eat + 128 : 0,
@@ -908,7 +915,7 @@
return NULL;
}
- if (skb_copy_bits(skb, skb_headlen(skb), skb->tail, delta))
+ if (skb_copy_bits(skb, skb_headlen(skb), skb_tail_pointer(skb), delta))
BUG();
/* Optimization: no fragments, no reasons to preestimate
@@ -1004,7 +1011,7 @@
skb->tail += delta;
skb->data_len -= delta;
- return skb->tail;
+ return skb_tail_pointer(skb);
}
/* Copy some data bits from skb to kernel buffer. */
@@ -1539,7 +1546,7 @@
skb1->len += skb1->data_len;
skb->data_len = 0;
skb->len = len;
- skb->tail = skb->data + len;
+ skb_set_tail_pointer(skb, len);
}
static inline void skb_split_no_header(struct sk_buff *skb,
diff --git a/net/core/wireless.c b/net/core/wireless.c
index 7c6a5db..4a777b6 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -1938,7 +1938,7 @@
{
struct ifinfomsg *r;
struct nlmsghdr *nlh;
- unsigned char *b = skb->tail;
+ unsigned char *b = skb_tail_pointer(skb);
nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r));
r = NLMSG_DATA(nlh);
@@ -1952,7 +1952,7 @@
/* Add the wireless events in the netlink packet */
RTA_PUT(skb, IFLA_WIRELESS, event_len, event);
- nlh->nlmsg_len = skb->tail - b;
+ nlh->nlmsg_len = skb_tail_pointer(skb) - b;
return skb->len;
nlmsg_failure: