All the ethernet drivers do this in their Rx ISR::
skb = dev_alloc_skb(length);
...
skb_reserve(skb,2); /* Force 16 byte alignment */
This patch collapses these into a single call
(dev_hdr_alloc_skb) which has the same number of
instructions as dev_alloc_skb.
So instead of the above we can simply use:
skb = dev_hdr_alloc_skb(length, ETH_HLEN);
This function can be used for other L2's, however note that
it will align the L3 data on a 32 bit boundary only. This
just happens to be a 16 byte boundary for Ethernet.
--- linux-2.3.99-pre1/include/linux/skbuff.h Tue Mar 14 21:20:48 2000
+++ linux/include/linux/skbuff.h Tue Mar 21 23:24:36 2000
@@ -626,6 +626,25 @@
return skb;
}
+/*
+ * Like dev_alloc_skb, except we are passed the length of the L2 layer's
+ * header (eg the Ethernet MAC header). We allocate and then reserve
+ * 0 to 3 bytes of additional room in the skb to ensure that the Layer 3
+ * data will start on a longword boundary
+ */
+
+extern __inline__ struct sk_buff *
+dev_hdr_alloc_skb(unsigned int length, const int proto_hdr_length)
+{
+ struct sk_buff *skb;
+ const int xlength = ((4 - (proto_hdr_length & 3)) & 3 ) + 16;
+
+ skb = alloc_skb(length+xlength, GFP_ATOMIC);
+ if (skb)
+ skb_reserve(skb,xlength);
+ return skb;
+}
+
extern __inline__ struct sk_buff *
skb_cow(struct sk_buff *skb, unsigned int headroom)
{
|