Skip to content

Commit 219badf

Browse files
edumazetdavem330
authored andcommitted
ipv6: frags: get rid of ip6frag_skb_cb/FRAG6_CB
ip6_frag_queue uses skb->cb[] to store the fragment offset, meaning that we could use two cache lines per skb when finding the insertion point, if for some reason inet6_skb_parm size is increased in the future. By using skb->ip_defrag_offset instead of skb->cb[], we pack all the fields in a single cache line, matching what we did for IPv4. Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent bf66337 commit 219badf

File tree

1 file changed

+12
-18
lines changed

1 file changed

+12
-18
lines changed

net/ipv6/reassembly.c

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@
6262

6363
static const char ip6_frag_cache_name[] = "ip6-frags";
6464

65-
struct ip6frag_skb_cb {
66-
struct inet6_skb_parm h;
67-
int offset;
68-
};
69-
70-
#define FRAG6_CB(skb) ((struct ip6frag_skb_cb *)((skb)->cb))
71-
7265
static u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h)
7366
{
7467
return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK);
@@ -250,13 +243,13 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
250243
* this fragment, right?
251244
*/
252245
prev = fq->q.fragments_tail;
253-
if (!prev || FRAG6_CB(prev)->offset < offset) {
246+
if (!prev || prev->ip_defrag_offset < offset) {
254247
next = NULL;
255248
goto found;
256249
}
257250
prev = NULL;
258251
for (next = fq->q.fragments; next != NULL; next = next->next) {
259-
if (FRAG6_CB(next)->offset >= offset)
252+
if (next->ip_defrag_offset >= offset)
260253
break; /* bingo! */
261254
prev = next;
262255
}
@@ -271,14 +264,20 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
271264

272265
/* Check for overlap with preceding fragment. */
273266
if (prev &&
274-
(FRAG6_CB(prev)->offset + prev->len) > offset)
267+
(prev->ip_defrag_offset + prev->len) > offset)
275268
goto discard_fq;
276269

277270
/* Look for overlap with succeeding segment. */
278-
if (next && FRAG6_CB(next)->offset < end)
271+
if (next && next->ip_defrag_offset < end)
279272
goto discard_fq;
280273

281-
FRAG6_CB(skb)->offset = offset;
274+
/* Note : skb->ip_defrag_offset and skb->dev share the same location */
275+
dev = skb->dev;
276+
if (dev)
277+
fq->iif = dev->ifindex;
278+
/* Makes sure compiler wont do silly aliasing games */
279+
barrier();
280+
skb->ip_defrag_offset = offset;
282281

283282
/* Insert this fragment in the chain of fragments. */
284283
skb->next = next;
@@ -289,11 +288,6 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
289288
else
290289
fq->q.fragments = skb;
291290

292-
dev = skb->dev;
293-
if (dev) {
294-
fq->iif = dev->ifindex;
295-
skb->dev = NULL;
296-
}
297291
fq->q.stamp = skb->tstamp;
298292
fq->q.meat += skb->len;
299293
fq->ecn |= ecn;
@@ -380,7 +374,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
380374
}
381375

382376
WARN_ON(head == NULL);
383-
WARN_ON(FRAG6_CB(head)->offset != 0);
377+
WARN_ON(head->ip_defrag_offset != 0);
384378

385379
/* Unfragmented part is taken from the first segment. */
386380
payload_len = ((head->data - skb_network_header(head)) -

0 commit comments

Comments
 (0)