aboutsummaryrefslogtreecommitdiff
path: root/pfinet
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2023-02-19 22:24:32 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-02-19 22:26:47 +0100
commit67efb746c492c25fac4d77aa16b808a8aa26089d (patch)
tree3031425a1909281b06a0b69600bb4f00cb0c3ca2 /pfinet
parentb8bcd4eb1438721f6a52bfd1e458307d4e105d89 (diff)
downloadhurd-67efb746c492c25fac4d77aa16b808a8aa26089d.tar.gz
hurd-67efb746c492c25fac4d77aa16b808a8aa26089d.tar.bz2
hurd-67efb746c492c25fac4d77aa16b808a8aa26089d.zip
pfinet: Align packets
The Ethernet header is 14 bytes long, and thus leads to IP header misalignment. This uses skb_reserve to introduce 2 bytes of padding to realign IP headers.
Diffstat (limited to 'pfinet')
-rw-r--r--pfinet/ethernet.c3
-rw-r--r--pfinet/linux-src/include/linux/skbuff.h24
-rw-r--r--pfinet/tunnel.c3
3 files changed, 28 insertions, 2 deletions
diff --git a/pfinet/ethernet.c b/pfinet/ethernet.c
index c317820c..82c318b2 100644
--- a/pfinet/ethernet.c
+++ b/pfinet/ethernet.c
@@ -153,7 +153,8 @@ ethernet_demuxer (mach_msg_header_t *inp,
+ msg->packet_type.msgt_number - sizeof (struct packet_header);
pthread_mutex_lock (&net_bh_lock);
- skb = alloc_skb (datalen, GFP_ATOMIC);
+ skb = alloc_skb (NET_IP_ALIGN + datalen, GFP_ATOMIC);
+ skb_reserve(skb, NET_IP_ALIGN);
skb_put (skb, datalen);
skb->dev = dev;
diff --git a/pfinet/linux-src/include/linux/skbuff.h b/pfinet/linux-src/include/linux/skbuff.h
index 00f9ab2a..46eb995e 100644
--- a/pfinet/linux-src/include/linux/skbuff.h
+++ b/pfinet/linux-src/include/linux/skbuff.h
@@ -498,6 +498,30 @@ static __inline__ int skb_tailroom(struct sk_buff *skb)
return skb->end-skb->tail;
}
+/*
+ * CPUs often take a performance hit when accessing unaligned memory
+ * locations. The actual performance hit varies, it can be small if the
+ * hardware handles it or large if we have to take an exception and fix it
+ * in software.
+ *
+ * Since an ethernet header is 14 bytes network drivers often end up with
+ * the IP header at an unaligned offset. The IP header can be aligned by
+ * shifting the start of the packet by 2 bytes. Drivers should do this
+ * with:
+ *
+ * skb_reserve(skb, NET_IP_ALIGN);
+ *
+ * The downside to this alignment of the IP header is that the DMA is now
+ * unaligned. On some architectures the cost of an unaligned DMA is high
+ * and this cost outweighs the gains made by aligning the IP header.
+ *
+ * Since this trade off varies between architectures, we allow NET_IP_ALIGN
+ * to be overridden.
+ */
+#ifndef NET_IP_ALIGN
+#define NET_IP_ALIGN 2
+#endif
+
static __inline__ void skb_reserve(struct sk_buff *skb, unsigned int len)
{
skb->data+=len;
diff --git a/pfinet/tunnel.c b/pfinet/tunnel.c
index e11ab670..b519ebd1 100644
--- a/pfinet/tunnel.c
+++ b/pfinet/tunnel.c
@@ -391,7 +391,8 @@ trivfs_S_io_write (struct trivfs_protid *cred,
pthread_mutex_lock (&tdev->lock);
pthread_mutex_lock (&net_bh_lock);
- skb = alloc_skb (datalen, GFP_ATOMIC);
+ skb = alloc_skb (NET_IP_ALIGN + datalen, GFP_ATOMIC);
+ skb_reserve(skb, NET_IP_ALIGN);
skb->len = datalen;
skb->dev = &tdev->dev;