ia64/xen-unstable

changeset 170:ac77b60e57a6

bitkeeper revision 1.36 (3e4d1c9bh5tZF-JT9Immw5NWGJ6juw)

pre-checkin cleanup
author akw27@boulderdash.cl.cam.ac.uk
date Fri Feb 14 16:43:07 2003 +0000 (2003-02-14)
parents f5723f60515a
children cf76e69e6979
files xen-2.4.16/net/dev.c xen-2.4.16/net/skbuff.c xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c xenolinux-2.4.16-sparse/net/core/skbuff.c
line diff
     1.1 --- a/xen-2.4.16/net/dev.c	Fri Feb 14 16:23:58 2003 +0000
     1.2 +++ b/xen-2.4.16/net/dev.c	Fri Feb 14 16:43:07 2003 +0000
     1.3 @@ -507,7 +507,13 @@ int dev_queue_xmit(struct sk_buff *skb)
     1.4  {
     1.5  	struct net_device *dev = skb->dev;
     1.6  	struct Qdisc  *q;
     1.7 -if (!(dev->features&NETIF_F_SG)) printk("NIC doesn't do SG!!!\n");
     1.8 +        
     1.9 +        if (!(dev->features&NETIF_F_SG)) 
    1.10 +        {
    1.11 +            printk("NIC doesn't do scatter-gather!\n");
    1.12 +            BUG();
    1.13 +        }
    1.14 +        
    1.15  	if (skb_shinfo(skb)->frag_list &&
    1.16  	    !(dev->features&NETIF_F_FRAGLIST) &&
    1.17  	    skb_linearize(skb, GFP_ATOMIC) != 0) {
    1.18 @@ -679,30 +685,16 @@ void deliver_packet(struct sk_buff *skb,
    1.19  {
    1.20          net_shadow_ring_t *shadow_ring;
    1.21          rx_shadow_entry_t *rx;
    1.22 -        unsigned long *g_pte; //tmp
    1.23 +        unsigned long *g_pte; 
    1.24          struct pfn_info *g_pfn, *h_pfn;
    1.25 -        unsigned int i; //, nvif;
    1.26 +        unsigned int i; 
    1.27  
    1.28          
    1.29          
    1.30 -        /*
    1.31 -         * Write the virtual MAC address into the destination field
    1.32 -         * of the ethernet packet. Furthermore, do the same for ARP
    1.33 -         * reply packets. This is easy because the virtual MAC address
    1.34 -         * is always 00-[nn]-00-00-00-00, where the second sixteen bits 
    1.35 -         * of the MAC are the vif's id.  This is to differentiate between
    1.36 -         * vifs on guests that have more than one.
    1.37 -         *
    1.38 -         * In zero copy, the data pointers for the packet have to have been 
    1.39 -         * mapped in by the caller.
    1.40 -         */
    1.41 -
    1.42          memset(skb->mac.ethernet->h_dest, 0, ETH_ALEN);
    1.43 -//        *(unsigned int *)(skb->mac.ethernet->h_dest + 1) = nvif;
    1.44          if ( ntohs(skb->mac.ethernet->h_proto) == ETH_P_ARP )
    1.45          {
    1.46              memset(skb->nh.raw + 18, 0, ETH_ALEN);
    1.47 -//            *(unsigned int *)(skb->nh.raw + 18 + 1) = nvif;
    1.48          }
    1.49          shadow_ring = vif->shadow_ring;
    1.50  
    1.51 @@ -789,14 +781,17 @@ int netif_rx(struct sk_buff *skb)
    1.52  	    get_fast_time(&skb->stamp);
    1.53  
    1.54          if ( (skb->data - skb->head) != (18 + ETH_HLEN) )
    1.55 -            printk("headroom was %lu!\n", (unsigned long)skb->data - (unsigned long)skb->head);
    1.56 -        //    BUG();
    1.57 +            BUG();
    1.58          
    1.59          skb->head = (u8 *)map_domain_mem(((skb->pf - frame_table) << PAGE_SHIFT));
    1.60  
    1.61          /* remapping this address really screws up all the skb pointers.  We need 
    1.62 -        * to map them all here sufficiently to get the packet demultiplexed.
    1.63 -        */
    1.64 +         * to map them all here sufficiently to get the packet demultiplexed.
    1.65 +         *
    1.66 +         * this remapping happens more than once in the code and is grim.  It will
    1.67 +         * be fixed in a later update -- drivers should be able to align the packet
    1.68 +         * arbitrarily.
    1.69 +         */
    1.70                  
    1.71          skb->data = skb->head;
    1.72          skb_reserve(skb,18); // 18 is the 16 from dev_alloc_skb plus 2 for #
    1.73 @@ -805,9 +800,6 @@ int netif_rx(struct sk_buff *skb)
    1.74          skb->data += ETH_HLEN;
    1.75          skb->nh.raw = skb->data;
    1.76          
    1.77 -	/* The code is rearranged so that the path is the most
    1.78 -	   short when CPU is congested, but is still operating.
    1.79 -	 */
    1.80  	queue = &softnet_data[this_cpu];
    1.81          
    1.82  	netdev_rx_stat[this_cpu].total++;
    1.83 @@ -817,15 +809,9 @@ int netif_rx(struct sk_buff *skb)
    1.84                  
    1.85          if ( skb->dst_vif == VIF_UNKNOWN_INTERFACE )
    1.86              skb->dst_vif = __net_get_target_vif(skb->mac.raw, skb->len, skb->src_vif);
    1.87 -//if (skb->dst_vif == VIF_DROP)
    1.88 -//printk("netif_rx target: %d (sec: %u)\n", skb->dst_vif, skb->security);
    1.89          
    1.90          if ( (vif = sys_vif_list[skb->dst_vif]) == NULL )
    1.91 -        {
    1.92 -//printk("No such vif! (%d).\n", skb->dst_vif);
    1.93 -            // the target vif does not exist.
    1.94              goto drop;
    1.95 -        }
    1.96  
    1.97          /* This lock-and-walk of the task list isn't really necessary, and is an
    1.98           * artifact of the old code.  The vif contains a pointer to the skb list 
    1.99 @@ -985,6 +971,16 @@ static inline void handle_diverter(struc
   1.100  }
   1.101  #endif   /* CONFIG_NET_DIVERT */
   1.102  
   1.103 +
   1.104 +/*
   1.105 + * update_shared_ring(void)
   1.106 + *
   1.107 + * This replaces flush_rx_queue as the guest event handler to move packets queued in
   1.108 + * the guest ring up to the guest.  Really, the packet is already there, it was page
   1.109 + * flipped in deliver_packet, but this moves the ring descriptor across from the 
   1.110 + * shadow ring and increments the pointers.
   1.111 + */
   1.112 +
   1.113  void update_shared_ring(void)
   1.114  {
   1.115      rx_shadow_entry_t *rx;
   1.116 @@ -1017,156 +1013,6 @@ void update_shared_ring(void)
   1.117      }
   1.118  }
   1.119              
   1.120 -void flush_rx_queue(void)
   1.121 -{
   1.122 -    struct sk_buff *skb;
   1.123 -    shared_info_t *s = current->shared_info;
   1.124 -    net_ring_t *net_ring;
   1.125 -    net_shadow_ring_t *shadow_ring;
   1.126 -    unsigned int i, nvif;
   1.127 -    rx_shadow_entry_t *rx;
   1.128 -    unsigned long *g_pte, tmp;
   1.129 -    struct pfn_info *g_pfn, *h_pfn;
   1.130 -    
   1.131 -    /* I have changed this to batch flush all vifs for a guest
   1.132 -     * at once, whenever this is called.  Since the guest is about to be
   1.133 -     * scheduled and issued an RX interrupt for one nic, it might as well
   1.134 -     * receive all pending traffic  although it will still only get
   1.135 -     * interrupts about rings that pass the event marker.  
   1.136 -     *
   1.137 -     * If this doesn't make sense, _HYP_EVENT_NET_RX can be modified to
   1.138 -     * represent individual interrups as _EVENT_NET_RX and the outer for
   1.139 -     * loop can be replaced with a translation to the specific NET 
   1.140 -     * interrupt to serve. --akw
   1.141 -     */
   1.142 -    clear_bit(_HYP_EVENT_NET_RX, &current->hyp_events);
   1.143 -
   1.144 -    for (nvif = 0; nvif < current->num_net_vifs; nvif++)
   1.145 -    {
   1.146 -        net_ring = current->net_vif_list[nvif]->net_ring;
   1.147 -        shadow_ring = current->net_vif_list[nvif]->shadow_ring;
   1.148 -        while ( (skb = skb_dequeue(&current->net_vif_list[nvif]->skb_list)) 
   1.149 -                        != NULL )
   1.150 -        {
   1.151 -            //temporary hack to stop processing non-zc skbs.
   1.152 -            if (skb->skb_type == SKB_NORMAL) continue;
   1.153 -            /*
   1.154 -             * Write the virtual MAC address into the destination field
   1.155 -             * of the ethernet packet. Furthermore, do the same for ARP
   1.156 -             * reply packets. This is easy because the virtual MAC address
   1.157 -             * is always 00-00-00-00-00-00.
   1.158 -             *
   1.159 -             * Actually, the MAC address is now all zeros, except for the
   1.160 -             * second sixteen bits, which are the per-host vif id.
   1.161 -             * (so eth0 should be 00-00-..., eth1 is 00-01-...)
   1.162 -             */
   1.163 -            
   1.164 -            if (skb->skb_type == SKB_ZERO_COPY)
   1.165 -            {
   1.166 -                skb->head = (u8 *)map_domain_mem(((skb->pf - frame_table) << PAGE_SHIFT));
   1.167 -                skb->data = skb->head;
   1.168 -                skb_reserve(skb,16); 
   1.169 -                skb->mac.raw = skb->data;
   1.170 -                skb->data += ETH_HLEN;
   1.171 -            }
   1.172 -            
   1.173 -            memset(skb->mac.ethernet->h_dest, 0, ETH_ALEN);
   1.174 -            *(unsigned int *)(skb->mac.ethernet->h_dest + 1) = nvif;
   1.175 -            if ( ntohs(skb->mac.ethernet->h_proto) == ETH_P_ARP )
   1.176 -            {
   1.177 -                memset(skb->nh.raw + 18, 0, ETH_ALEN);
   1.178 -                *(unsigned int *)(skb->nh.raw + 18 + 1) = nvif;
   1.179 -            }
   1.180 -
   1.181 -            if (skb->skb_type == SKB_ZERO_COPY)
   1.182 -            {
   1.183 -                unmap_domain_mem(skb->head);
   1.184 -            }
   1.185 -
   1.186 -            i = net_ring->rx_cons;
   1.187 -            if ( i != net_ring->rx_prod )
   1.188 -            {
   1.189 -                net_ring->rx_ring[i].status = shadow_ring->rx_ring[i].status;
   1.190 -                if ( shadow_ring->rx_ring[i].status == RING_STATUS_OK)
   1.191 -                {
   1.192 -                    rx = shadow_ring->rx_ring+i;
   1.193 -                    if ( (skb->len + ETH_HLEN) < rx->size )
   1.194 -                        rx->size = skb->len + ETH_HLEN;
   1.195 -
   1.196 -                    /* remap the packet again.  This is very temporary and will shortly be
   1.197 -                     * replaced with a page swizzle.
   1.198 -                     */
   1.199 -
   1.200 -                    /*if (skb->skb_type == SKB_ZERO_COPY)
   1.201 -                    {
   1.202 -                        skb->head = (u8 *)map_domain_mem(((skb->pf - frame_table) << PAGE_SHIFT));
   1.203 -                        skb->data = skb->head;
   1.204 -                        skb_reserve(skb,16); 
   1.205 -                        skb->mac.raw = skb->data;
   1.206 -                        skb->data += ETH_HLEN;
   1.207 -                    }
   1.208 -                                                                        
   1.209 -                    copy_to_user((void *)rx->addr, skb->mac.raw, rx->size);
   1.210 -                    copy_to_user(net_ring->rx_ring+i, rx, sizeof(rx));
   1.211 -                    
   1.212 -                    if (skb->skb_type == SKB_ZERO_COPY)
   1.213 -                    {
   1.214 -                        unmap_domain_mem(skb->head);
   1.215 -                        skb->head = skb->data = skb->tail = (void *)0xdeadbeef;
   1.216 -                    }*/
   1.217 -
   1.218 -                    //presumably I don't need to rewalk the guest page table
   1.219 -                    //here.
   1.220 -                    if (skb->skb_type == SKB_ZERO_COPY) 
   1.221 -                    {
   1.222 -                        // g_pfn is the frame FROM the guest being given up
   1.223 -                        // h_pfn is the frame FROM the hypervisor, passing up.
   1.224 -                        
   1.225 -                        if (rx->flush_count == tlb_flush_count[smp_processor_id()])
   1.226 -                        {
   1.227 -                            flush_tlb_all();
   1.228 -                        }
   1.229 -                        
   1.230 -                        g_pte = map_domain_mem(rx->addr);
   1.231 -                        
   1.232 -                        //g_pfn = frame_table + (rx->addr >> PAGE_SHIFT);
   1.233 -                        g_pfn =  frame_table + (*g_pte >> PAGE_SHIFT);
   1.234 -                        h_pfn = skb->pf;
   1.235 -
   1.236 -
   1.237 -                        //tmp = g_pfn->next; g_pfn->next = h_pfn->next; h_pfn->next = tmp;
   1.238 -                        //tmp = g_pfn->prev; g_pfn->prev = h_pfn->prev; h_pfn->prev = tmp;
   1.239 -                        tmp = g_pfn->flags; g_pfn->flags = h_pfn->flags; h_pfn->flags = tmp;
   1.240 -                        
   1.241 -                        h_pfn->tot_count = 1;
   1.242 -                        h_pfn->type_count = g_pfn->type_count;
   1.243 -                        g_pfn->tot_count = g_pfn->type_count = 0;
   1.244 -                        
   1.245 -                        h_pfn->flags = current->domain | PGT_l1_page_table;
   1.246 -                        g_pfn->flags = PGT_l1_page_table;
   1.247 -
   1.248 -
   1.249 -                        *g_pte = (*g_pte & ~PAGE_MASK) | (((h_pfn - frame_table) << PAGE_SHIFT) & PAGE_MASK);
   1.250 -
   1.251 -                        *g_pte |= _PAGE_PRESENT;
   1.252 -                        unmap_domain_mem(g_pte);
   1.253 -
   1.254 -                        skb->pf = g_pfn; // return the guest pfn to be put on the free list
   1.255 -                    } else {
   1.256 -                        BUG(); //got a non-zero copy skb.  which is not good.
   1.257 -                    }
   1.258 -                    
   1.259 -                }
   1.260 -                net_ring->rx_cons = (i+1) & (RX_RING_SIZE-1);
   1.261 -                if ( net_ring->rx_cons == net_ring->rx_event )
   1.262 -                    set_bit(_EVENT_NET_RX, &s->events);
   1.263 -            }
   1.264 -            kfree_skb(skb);
   1.265 -        }
   1.266 -    }
   1.267 -}
   1.268 -
   1.269 -
   1.270  /*
   1.271   *	Map an interface index to its name (SIOCGIFNAME)
   1.272   */
   1.273 @@ -2180,16 +2026,6 @@ void tx_skb_release(struct sk_buff *skb)
   1.274   */
   1.275  #define PKT_PROT_LEN (ETH_HLEN + 8)
   1.276  
   1.277 -void print_range2(u8 *start, unsigned int len)
   1.278 -{
   1.279 -    int i=0;
   1.280 -    while (i++ < len)
   1.281 -    {
   1.282 -        printk("%x:",start[i]);
   1.283 -    }
   1.284 -    printk("\n");
   1.285 -}
   1.286 -
   1.287  long do_net_update(void)
   1.288  {
   1.289      shared_info_t *shared = current->shared_info;    
     2.1 --- a/xen-2.4.16/net/skbuff.c	Fri Feb 14 16:23:58 2003 +0000
     2.2 +++ b/xen-2.4.16/net/skbuff.c	Fri Feb 14 16:43:07 2003 +0000
     2.3 @@ -150,8 +150,6 @@ static __inline__ void skb_head_to_pool(
     2.4  	kmem_cache_free(skbuff_head_cache, skb);
     2.5  }
     2.6  
     2.7 -//static unsigned long skbpagesout=0, skbpagesin=0;
     2.8 -
     2.9  static inline u8 *alloc_skb_data_page(struct sk_buff *skb)
    2.10  {
    2.11          struct list_head *list_ptr;
    2.12 @@ -166,13 +164,11 @@ static inline u8 *alloc_skb_data_page(st
    2.13          pf = list_entry(list_ptr, struct pfn_info, list);
    2.14          pf->flags = 0; // owned by dom0
    2.15          list_del(&pf->list);
    2.16 -        //pf->next = pf->prev = (pf - frame_table);
    2.17          free_pfns--;
    2.18  
    2.19          spin_unlock_irqrestore(&free_list_lock, flags);
    2.20  
    2.21          skb->pf = pf;
    2.22 -//if (skbpagesout++ % 100 == 0) printk("XEN-: skb allocs: %lu\n", skbpagesout);
    2.23          return (u8 *)((pf - frame_table) << PAGE_SHIFT);
    2.24  }
    2.25  
    2.26 @@ -190,7 +186,6 @@ static inline void dealloc_skb_data_page
    2.27  
    2.28          spin_unlock_irqrestore(&free_list_lock, flags);
    2.29  
    2.30 -//if (skbpagesin++ % 100 == 0) printk("XEN-: skb allocs: %lu\n", skbpagesin);
    2.31  }
    2.32  
    2.33  struct sk_buff *alloc_zc_skb(unsigned int size,int gfp_mask)
    2.34 @@ -406,10 +401,16 @@ static void skb_release_data(struct sk_b
    2.35  		if (skb_shinfo(skb)->frag_list)
    2.36  			skb_drop_fraglist(skb);
    2.37  
    2.38 -                if (skb->skb_type == SKB_NORMAL) {
    2.39 +                if (skb->skb_type == SKB_NORMAL) 
    2.40 +                {
    2.41  		    kfree(skb->head);
    2.42 -                } else if (skb->skb_type == SKB_ZERO_COPY) {                    dealloc_skb_data_page(skb);
    2.43 -                } else {
    2.44 +                } 
    2.45 +                else if (skb->skb_type == SKB_ZERO_COPY) 
    2.46 +                {
    2.47 +                    dealloc_skb_data_page(skb);
    2.48 +                } 
    2.49 +                else 
    2.50 +                {
    2.51                      BUG(); //skb_release_data called with unknown skb type!
    2.52                  }
    2.53  	}
     3.1 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c	Fri Feb 14 16:23:58 2003 +0000
     3.2 +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c	Fri Feb 14 16:43:07 2003 +0000
     3.3 @@ -186,35 +186,7 @@ inline unsigned long get_ppte(unsigned l
     3.4  
     3.5          return ppte;
     3.6  }
     3.7 -/*
     3.8 -static void validate_free_list(void)
     3.9 -{
    3.10 -    unsigned long addr, ppfn, mpfn, mpfn2, flags;
    3.11 -    struct list_head *i;
    3.12 -    struct net_page_info *np;
    3.13  
    3.14 -    printk(KERN_ALERT "Walking free pages:\n");
    3.15 -   
    3.16 -    spin_lock_irqsave(&net_page_list_lock, flags);
    3.17 -    
    3.18 -    list_for_each(i, &net_page_list) 
    3.19 -    {
    3.20 -        np = list_entry(i, struct net_page_info, list);
    3.21 -        addr = np->virt_addr;
    3.22 -        ppfn = virt_to_phys(addr) >> PAGE_SHIFT;
    3.23 -        mpfn = get_ppte(addr);
    3.24 -        mpfn2 = phys_to_machine_mapping[ppfn];
    3.25 -
    3.26 -        mpfn = (*(unsigned long *)phys_to_virt(machine_to_phys(mpfn))) >> PAGE_SHIFT;
    3.27 -        if (mpfn != mpfn2) printk(KERN_ALERT "mpfn %lu != %lu\n", mpfn, mpfn2);
    3.28 -
    3.29 -        if (machine_to_phys_mapping[mpfn] != ppfn) printk(KERN_ALERT "ppfn %lu != %lu\n", machine_to_phys_mapping[mpfn], ppfn);
    3.30 -    }
    3.31 -
    3.32 -    spin_unlock_irqrestore(&net_page_list_lock, flags);
    3.33 -    
    3.34 -}
    3.35 -*/
    3.36  static void network_alloc_rx_buffers(struct net_device *dev)
    3.37  {
    3.38      unsigned int i;
    3.39 @@ -232,7 +204,6 @@ static void network_alloc_rx_buffers(str
    3.40          np->rx_skb_ring[i] = skb;
    3.41          np->net_ring->rx_ring[i].addr = get_ppte(skb->head); 
    3.42          np->net_ring->rx_ring[i].size = RX_BUF_SIZE - 16; /* arbitrary */
    3.43 -//printk(KERN_ALERT "[%p]\n", phys_to_machine(virt_to_phys(skb->page_ptr)));
    3.44      }
    3.45  
    3.46      np->net_ring->rx_prod = i;
    3.47 @@ -256,15 +227,6 @@ static void network_free_rx_buffers(stru
    3.48      }
    3.49  }
    3.50  
    3.51 -void print_range(u8 *start, unsigned int len)
    3.52 -{
    3.53 -    int i = 0;
    3.54 -
    3.55 -    while (i++ < len)
    3.56 -        printk("%x:", start[i]);
    3.57 -    printk("\n");
    3.58 -}
    3.59 -
    3.60  static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
    3.61  {
    3.62      unsigned int i;
    3.63 @@ -276,9 +238,6 @@ static int network_start_xmit(struct sk_
    3.64          netif_stop_queue(dev);
    3.65          return -ENOBUFS;
    3.66      }
    3.67 -//print_range(skb->data, ETH_HLEN + 8);
    3.68 -//print_range(skb->data + ETH_HLEN + 8, 20);
    3.69 -//printk("skb->len is %u in guestOS (expected fraglen: %u).\n", skb->len, skb->len - (ETH_HLEN + 8));
    3.70      i = np->net_ring->tx_prod;
    3.71  
    3.72      if ( (((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= PAGE_SIZE )
    3.73 @@ -331,8 +290,6 @@ static void network_rx_int(int irq, void
    3.74      struct net_private *np = dev->priv;
    3.75      struct sk_buff *skb;
    3.76      
    3.77 -    /*if (net_countx++ % 100 == 0) validate_free_list();*/
    3.78 -    
    3.79   again:
    3.80      for ( i = np->rx_idx; i != np->net_ring->rx_cons; i = RX_RING_INC(i) )
    3.81      {
    3.82 @@ -344,8 +301,6 @@ static void network_rx_int(int irq, void
    3.83          }
    3.84          skb = np->rx_skb_ring[i];
    3.85  
    3.86 -//printk(KERN_ALERT "[%u]: ptmm[%lx] old:(%lx) new:(%lx)\n", i , virt_to_phys(skb->head) >> PAGE_SHIFT, phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT], (*(unsigned long *)phys_to_virt(machine_to_phys(np->net_ring->rx_ring[i].addr))) >> PAGE_SHIFT);
    3.87 -
    3.88          phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT] =
    3.89              (*(unsigned long *)phys_to_virt(
    3.90                      machine_to_phys(np->net_ring->rx_ring[i].addr))
    3.91 @@ -354,8 +309,8 @@ static void network_rx_int(int irq, void
    3.92          skb_put(skb, np->net_ring->rx_ring[i].size);
    3.93          skb->protocol = eth_type_trans(skb, dev);
    3.94  
    3.95 -        /* Set up shinfo -- from alloc_skb */
    3.96 -        /* This was particularily nasty:  the shared info is hidden at the back of the data area
    3.97 +        /* Set up shinfo -- from alloc_skb 
    3.98 +         * This was particularily nasty:  the shared info is hidden at the back of the data area
    3.99           * (presumably so it can be shared), but on page flip it gets very spunked.
   3.100           */
   3.101  
     4.1 --- a/xenolinux-2.4.16-sparse/net/core/skbuff.c	Fri Feb 14 16:23:58 2003 +0000
     4.2 +++ b/xenolinux-2.4.16-sparse/net/core/skbuff.c	Fri Feb 14 16:43:07 2003 +0000
     4.3 @@ -433,6 +433,7 @@ static void skb_release_data(struct sk_b
     4.4  	    atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) {
     4.5  		if (skb_shinfo(skb)->nr_frags) {
     4.6  			int i;
     4.7 +printk("there were %u frags!\n", skb_shinfo(skb)->nr_frags);
     4.8  			for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) 
     4.9  {
    4.10  				put_page(skb_shinfo(skb)->frags[i].page);
    4.11 @@ -442,14 +443,14 @@ static void skb_release_data(struct sk_b
    4.12  		if (skb_shinfo(skb)->frag_list)
    4.13  			skb_drop_fraglist(skb);
    4.14  
    4.15 -                if (skb->skb_type == SKB_NORMAL)
    4.16 -                {
    4.17 +                //if (skb->skb_type == SKB_NORMAL)
    4.18 +                //{
    4.19  		    kfree(skb->head);
    4.20 -                } else {// SKB_ZERO_COPY
    4.21 +                //} else {// SKB_ZERO_COPY
    4.22                      //free_net_page(skb->net_page);
    4.23  //printk(KERN_ALERT "<%p>\n", phys_to_machine(virt_to_phys(skb->head)));
    4.24 -                    free_page((void *)skb->head);
    4.25 -                }
    4.26 +                //    free_page((void *)skb->head);
    4.27 +                //}
    4.28  	}
    4.29  
    4.30  }