Skip to content

Commit f5184d2

Browse files
jmbergdavem330
authored andcommitted
net: Allow netdevices to specify needed head/tailroom
This patch adds needed_headroom/needed_tailroom members to struct net_device and updates many places that allocate sbks to use them. Not all of them can be converted though, and I'm sure I missed some (I mostly grepped for LL_RESERVED_SPACE) Signed-off-by: Johannes Berg <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8388e3d commit f5184d2

File tree

13 files changed

+39
-31
lines changed

13 files changed

+39
-31
lines changed

include/linux/netdevice.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,11 +246,16 @@ struct hh_cache
246246
*
247247
* We could use other alignment values, but we must maintain the
248248
* relationship HH alignment <= LL alignment.
249+
*
250+
* LL_ALLOCATED_SPACE also takes into account the tailroom the device
251+
* may need.
249252
*/
250253
#define LL_RESERVED_SPACE(dev) \
251-
(((dev)->hard_header_len&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
254+
((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
252255
#define LL_RESERVED_SPACE_EXTRA(dev,extra) \
253-
((((dev)->hard_header_len+extra)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
256+
((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
257+
#define LL_ALLOCATED_SPACE(dev) \
258+
((((dev)->hard_header_len+(dev)->needed_headroom+(dev)->needed_tailroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
254259

255260
struct header_ops {
256261
int (*create) (struct sk_buff *skb, struct net_device *dev,
@@ -569,6 +574,13 @@ struct net_device
569574
unsigned short type; /* interface hardware type */
570575
unsigned short hard_header_len; /* hardware hdr length */
571576

577+
/* extra head- and tailroom the hardware may need, but not in all cases
578+
* can this be guaranteed, especially tailroom. Some cases also use
579+
* LL_MAX_HEADER instead to allocate the skb.
580+
*/
581+
unsigned short needed_headroom;
582+
unsigned short needed_tailroom;
583+
572584
struct net_device *master; /* Pointer to master device of a group,
573585
* which this device is member of.
574586
*/

net/core/netpoll.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ static void arp_reply(struct sk_buff *skb)
419419
return;
420420

421421
size = arp_hdr_len(skb->dev);
422-
send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev),
422+
send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev),
423423
LL_RESERVED_SPACE(np->dev));
424424

425425
if (!send_skb)

net/econet/af_econet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
340340

341341
dev_hold(dev);
342342

343-
skb = sock_alloc_send_skb(sk, len+LL_RESERVED_SPACE(dev),
343+
skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
344344
msg->msg_flags & MSG_DONTWAIT, &err);
345345
if (skb==NULL)
346346
goto out_unlock;

net/ipv4/arp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
570570
* Allocate a buffer
571571
*/
572572

573-
skb = alloc_skb(arp_hdr_len(dev) + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
573+
skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
574574
if (skb == NULL)
575575
return NULL;
576576

net/ipv4/igmp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
292292
struct iphdr *pip;
293293
struct igmpv3_report *pig;
294294

295-
skb = alloc_skb(size + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
295+
skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
296296
if (skb == NULL)
297297
return NULL;
298298

@@ -653,7 +653,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
653653
return -1;
654654
}
655655

656-
skb=alloc_skb(IGMP_SIZE+LL_RESERVED_SPACE(dev), GFP_ATOMIC);
656+
skb=alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
657657
if (skb == NULL) {
658658
ip_rt_put(rt);
659659
return -1;

net/ipv4/ipconfig.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -710,14 +710,14 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
710710
struct net_device *dev = d->dev;
711711
struct sk_buff *skb;
712712
struct bootp_pkt *b;
713-
int hh_len = LL_RESERVED_SPACE(dev);
714713
struct iphdr *h;
715714

716715
/* Allocate packet */
717-
skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
716+
skb = alloc_skb(sizeof(struct bootp_pkt) + LL_ALLOCATED_SPACE(dev) + 15,
717+
GFP_KERNEL);
718718
if (!skb)
719719
return;
720-
skb_reserve(skb, hh_len);
720+
skb_reserve(skb, LL_RESERVED_SPACE(dev));
721721
b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt));
722722
memset(b, 0, sizeof(struct bootp_pkt));
723723

net/ipv4/raw.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,6 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
322322
unsigned int flags)
323323
{
324324
struct inet_sock *inet = inet_sk(sk);
325-
int hh_len;
326325
struct iphdr *iph;
327326
struct sk_buff *skb;
328327
unsigned int iphlen;
@@ -336,13 +335,12 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
336335
if (flags&MSG_PROBE)
337336
goto out;
338337

339-
hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
340-
341-
skb = sock_alloc_send_skb(sk, length+hh_len+15,
342-
flags&MSG_DONTWAIT, &err);
338+
skb = sock_alloc_send_skb(sk,
339+
length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
340+
flags & MSG_DONTWAIT, &err);
343341
if (skb == NULL)
344342
goto error;
345-
skb_reserve(skb, hh_len);
343+
skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev));
346344

347345
skb->priority = sk->sk_priority;
348346
skb->mark = sk->sk_mark;

net/ipv6/ip6_output.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
780780
* Allocate buffer.
781781
*/
782782

783-
if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
783+
if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
784784
NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
785785
IP6_INC_STATS(ip6_dst_idev(skb->dst),
786786
IPSTATS_MIB_FRAGFAILS);

net/ipv6/mcast.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,7 +1411,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
14111411
IPV6_TLV_PADN, 0 };
14121412

14131413
/* we assume size > sizeof(ra) here */
1414-
skb = sock_alloc_send_skb(sk, size + LL_RESERVED_SPACE(dev), 1, &err);
1414+
skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err);
14151415

14161416
if (!skb)
14171417
return NULL;
@@ -1790,7 +1790,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
17901790
payload_len = len + sizeof(ra);
17911791
full_len = sizeof(struct ipv6hdr) + payload_len;
17921792

1793-
skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err);
1793+
skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
17941794

17951795
if (skb == NULL) {
17961796
rcu_read_lock();

net/ipv6/ndisc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ static void __ndisc_send(struct net_device *dev,
479479

480480
skb = sock_alloc_send_skb(sk,
481481
(MAX_HEADER + sizeof(struct ipv6hdr) +
482-
len + LL_RESERVED_SPACE(dev)),
482+
len + LL_ALLOCATED_SPACE(dev)),
483483
1, &err);
484484
if (!skb) {
485485
ND_PRINTK0(KERN_ERR
@@ -1521,7 +1521,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
15211521

15221522
buff = sock_alloc_send_skb(sk,
15231523
(MAX_HEADER + sizeof(struct ipv6hdr) +
1524-
len + LL_RESERVED_SPACE(dev)),
1524+
len + LL_ALLOCATED_SPACE(dev)),
15251525
1, &err);
15261526
if (buff == NULL) {
15271527
ND_PRINTK0(KERN_ERR

net/ipv6/raw.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,6 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
609609
struct ipv6_pinfo *np = inet6_sk(sk);
610610
struct ipv6hdr *iph;
611611
struct sk_buff *skb;
612-
unsigned int hh_len;
613612
int err;
614613

615614
if (length > rt->u.dst.dev->mtu) {
@@ -619,13 +618,12 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
619618
if (flags&MSG_PROBE)
620619
goto out;
621620

622-
hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
623-
624-
skb = sock_alloc_send_skb(sk, length+hh_len+15,
625-
flags&MSG_DONTWAIT, &err);
621+
skb = sock_alloc_send_skb(sk,
622+
length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
623+
flags & MSG_DONTWAIT, &err);
626624
if (skb == NULL)
627625
goto error;
628-
skb_reserve(skb, hh_len);
626+
skb_reserve(skb, LL_RESERVED_SPACE(rt->u.dst.dev));
629627

630628
skb->priority = sk->sk_priority;
631629
skb->mark = sk->sk_mark;

net/packet/af_packet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
743743
if (len > dev->mtu+reserve)
744744
goto out_unlock;
745745

746-
skb = sock_alloc_send_skb(sk, len + LL_RESERVED_SPACE(dev),
746+
skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev),
747747
msg->msg_flags & MSG_DONTWAIT, &err);
748748
if (skb==NULL)
749749
goto out_unlock;

net/xfrm/xfrm_output.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
2525
struct dst_entry *dst = skb->dst;
2626
int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev)
2727
- skb_headroom(skb);
28+
int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
2829

29-
if (nhead > 0)
30-
return pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
30+
if (nhead > 0 || ntail > 0)
31+
return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
3132

32-
/* Check tail too... */
3333
return 0;
3434
}
3535

0 commit comments

Comments
 (0)