diff options
author | Andrew Gallatin <gallatin@myri.com> | 2007-12-05 05:31:42 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-12-05 08:37:32 -0500 |
commit | 621544eb8c3beaa859c75850f816dd9b056a00a3 (patch) | |
tree | 15c4375c8899ced48bd751eb139cfe9b3778bda9 | |
parent | 4e67d876ce07471e02be571038d5435a825f0215 (diff) |
[LRO]: fix lro_gen_skb() alignment
Add a field to the lro_mgr struct so that drivers can specify how much
padding is required to align layer 3 headers when a packet is copied
into a freshly allocated skb by inet_lro.c:lro_gen_skb(). Without
padding, skbs generated by LRO will cause alignment warnings on
architectures which require strict alignment (seen on sparc64).
Myri10GE is updated to use this field.
Signed-off-by: Andrew Gallatin <gallatin@myri.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/myri10ge/myri10ge.c | 1 | ||||
-rw-r--r-- | include/linux/inet_lro.h | 3 | ||||
-rw-r--r-- | net/ipv4/inet_lro.c | 3 |
3 files changed, 6 insertions, 1 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 0f306ddb5630..8def8657251f 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -1979,6 +1979,7 @@ static int myri10ge_open(struct net_device *dev) | |||
1979 | lro_mgr->lro_arr = mgp->rx_done.lro_desc; | 1979 | lro_mgr->lro_arr = mgp->rx_done.lro_desc; |
1980 | lro_mgr->get_frag_header = myri10ge_get_frag_header; | 1980 | lro_mgr->get_frag_header = myri10ge_get_frag_header; |
1981 | lro_mgr->max_aggr = myri10ge_lro_max_pkts; | 1981 | lro_mgr->max_aggr = myri10ge_lro_max_pkts; |
1982 | lro_mgr->frag_align_pad = 2; | ||
1982 | if (lro_mgr->max_aggr > MAX_SKB_FRAGS) | 1983 | if (lro_mgr->max_aggr > MAX_SKB_FRAGS) |
1983 | lro_mgr->max_aggr = MAX_SKB_FRAGS; | 1984 | lro_mgr->max_aggr = MAX_SKB_FRAGS; |
1984 | 1985 | ||
diff --git a/include/linux/inet_lro.h b/include/linux/inet_lro.h index 1246d46abbc0..80335b7d77c5 100644 --- a/include/linux/inet_lro.h +++ b/include/linux/inet_lro.h | |||
@@ -91,6 +91,9 @@ struct net_lro_mgr { | |||
91 | int max_desc; /* Max number of LRO descriptors */ | 91 | int max_desc; /* Max number of LRO descriptors */ |
92 | int max_aggr; /* Max number of LRO packets to be aggregated */ | 92 | int max_aggr; /* Max number of LRO packets to be aggregated */ |
93 | 93 | ||
94 | int frag_align_pad; /* Padding required to properly align layer 3 | ||
95 | * headers in generated skb when using frags */ | ||
96 | |||
94 | struct net_lro_desc *lro_arr; /* Array of LRO descriptors */ | 97 | struct net_lro_desc *lro_arr; /* Array of LRO descriptors */ |
95 | 98 | ||
96 | /* | 99 | /* |
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c index ac3b1d3dba2e..9a96c277393d 100644 --- a/net/ipv4/inet_lro.c +++ b/net/ipv4/inet_lro.c | |||
@@ -401,10 +401,11 @@ static struct sk_buff *lro_gen_skb(struct net_lro_mgr *lro_mgr, | |||
401 | int data_len = len; | 401 | int data_len = len; |
402 | int hdr_len = min(len, hlen); | 402 | int hdr_len = min(len, hlen); |
403 | 403 | ||
404 | skb = netdev_alloc_skb(lro_mgr->dev, hlen); | 404 | skb = netdev_alloc_skb(lro_mgr->dev, hlen + lro_mgr->frag_align_pad); |
405 | if (!skb) | 405 | if (!skb) |
406 | return NULL; | 406 | return NULL; |
407 | 407 | ||
408 | skb_reserve(skb, lro_mgr->frag_align_pad); | ||
408 | skb->len = len; | 409 | skb->len = len; |
409 | skb->data_len = len - hdr_len; | 410 | skb->data_len = len - hdr_len; |
410 | skb->truesize += true_size; | 411 | skb->truesize += true_size; |