hh_cache question.

From: Gleb Natapov (gleb@nbase.co.il)
Date: Tue Feb 29 2000 - 04:49:31 EST


Hello.

I have a question about hardware header caching in kernel 2.2.x.

Currently the size of the hh_data (in hh_cache structure) defined 16
bytes long, but what if I want to cache bigger header? How can I do
that?

I can't simply enlarge this buffer because ip_finish_output (in
include/net/ip.h) assumes that the size of the buffer is 16. The changes
in ip_finish_output will cause changes in every hard_header_cache
function out there (there is no much I should say).

I wrote small patch (against 2.2.14) that allows bigger header to be
cached (up to 32 bytes). It also changes ip_finish_output in such a way
that if larger cache will be needed one can simply enlarge size of
hh_data without changes in other parts of the kernel. But perhaps I've
missed something and there is better solution?

                                        Thanks.

                                                Gleb.

diff -ur -X exclude 2.2.14-fixed/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c
--- 2.2.14-fixed/drivers/net/myri_sbus.c Tue Jan 4 20:12:17 2000
+++ linux/drivers/net/myri_sbus.c Tue Feb 29 09:40:50 2000
@@ -743,16 +743,12 @@
 {
         unsigned short type = hh->hh_type;
         unsigned char *pad = (unsigned char *)hh->hh_data;
- struct ethhdr *eth = (struct ethhdr *)(pad + MYRI_PAD_LEN);
+ struct ethhdr *eth = (struct ethhdr *)pad;
         struct device *dev = neigh->dev;
 
         if (type == __constant_htons(ETH_P_802_3))
                 return -1;
 
- /* Refill MyriNet padding identifiers, this is just being anal. */
- pad[0] = MYRI_PAD_LEN;
- pad[1] = 0xab;
-
         eth->h_proto = type;
         memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
         memcpy(eth->h_dest, neigh->ha, dev->addr_len);
@@ -763,7 +759,7 @@
 /* Called by Address Resolution module to notify changes in address. */
 void myri_header_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr)
 {
- memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len);
+ memcpy((u8*)hh->hh_data, haddr, dev->addr_len);
 }
 
 static int myri_change_mtu(struct device *dev, int new_mtu)
diff -ur -X exclude 2.2.14-fixed/drivers/net/sbni.c linux/drivers/net/sbni.c
--- 2.2.14-fixed/drivers/net/sbni.c Tue Jan 4 20:12:17 2000
+++ linux/drivers/net/sbni.c Tue Feb 29 09:44:09 2000
@@ -287,7 +287,7 @@
 {
         unsigned short type = hh->hh_type;
         struct sbni_hard_header *sbni = (struct sbni_hard_header*)
- (((u8*)hh->hh_data) - 8);
+ ((u8*)hh->hh_data);
         struct device *dev = neigh->dev;
   
   
@@ -320,7 +320,7 @@
 
 static void sbni_header_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr)
 {
- memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len);
+ memcpy(((u8*)hh->hh_data) + 8, haddr, dev->addr_len);
 }
 
 
diff -ur -X exclude 2.2.14-fixed/include/linux/netdevice.h linux/include/linux/netdevice.h
--- 2.2.14-fixed/include/linux/netdevice.h Tue Jan 4 20:12:25 2000
+++ linux/include/linux/netdevice.h Tue Feb 29 10:50:56 2000
@@ -157,7 +157,7 @@
         int (*hh_output)(struct sk_buff *skb);
         rwlock_t hh_lock;
         /* cached hardware header; allow for machine alignment needs. */
- unsigned long hh_data[16/sizeof(unsigned long)];
+ unsigned long hh_data[32/sizeof(unsigned long)];
 };
 
 
diff -ur -X exclude 2.2.14-fixed/include/net/ip.h linux/include/net/ip.h
--- 2.2.14-fixed/include/net/ip.h Wed Oct 27 02:53:42 1999
+++ linux/include/net/ip.h Mon Feb 28 19:34:46 2000
@@ -148,7 +148,8 @@
 
         if (hh) {
                 read_lock_irq(&hh->hh_lock);
- memcpy(skb->data - 16, hh->hh_data, 16);
+ memcpy(skb->data - dev->hard_header_len, hh->hh_data,
+ dev->hard_header_len);
                 read_unlock_irq(&hh->hh_lock);
                 skb_push(skb, dev->hard_header_len);
                 return hh->hh_output(skb);
diff -ur -X exclude 2.2.14-fixed/net/ethernet/eth.c linux/net/ethernet/eth.c
--- 2.2.14-fixed/net/ethernet/eth.c Tue Jan 4 20:12:26 2000
+++ linux/net/ethernet/eth.c Mon Feb 28 19:28:38 2000
@@ -237,7 +237,7 @@
 int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
 {
         unsigned short type = hh->hh_type;
- struct ethhdr *eth = (struct ethhdr*)(((u8*)hh->hh_data) + 2);
+ struct ethhdr *eth = (struct ethhdr*)((u8*)hh->hh_data);
         struct device *dev = neigh->dev;
 
         if (type == __constant_htons(ETH_P_802_3))
@@ -255,7 +255,7 @@
 
 void eth_header_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr)
 {
- memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len);
+ memcpy((u8*)hh->hh_data, haddr, dev->addr_len);
 }
 
 #ifndef CONFIG_IP_ROUTER

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Feb 29 2000 - 21:00:21 EST