ia64/xen-unstable

changeset 253:1c21ed4799dc

bitkeeper revision 1.105.1.3 (3e5e550bzMuNp7GfT1LItXmDa_coaA)

network.c:
Fix up net ring handling -- set tx events a bit better.
author kaf24@labyrinth.cl.cam.ac.uk
date Thu Feb 27 18:12:27 2003 +0000 (2003-02-27)
parents 4c2710d5317e
children 2177b1e83599
files xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
line diff
     1.1 --- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c	Wed Feb 26 19:50:23 2003 +0000
     1.2 +++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c	Thu Feb 27 18:12:27 2003 +0000
     1.3 @@ -65,15 +65,17 @@ struct net_private
     1.4      spinlock_t tx_lock;
     1.5  };
     1.6  
     1.7 - 
     1.8 +
     1.9  static void dbg_network_int(int irq, void *dev_id, struct pt_regs *ptregs)
    1.10  {
    1.11 -  struct net_device *dev = (struct net_device *)dev_id;
    1.12 -  struct net_private *np = dev->priv;
    1.13 -  printk(KERN_ALERT "tx_full = %d, tx_entries = %d, tx_idx = %d, tx_cons = %d, tx_prod = %d, tx_event = %d, state=%d\n",
    1.14 -	 np->tx_full, np->tx_entries, np->tx_idx, 
    1.15 -	 np->net_ring->tx_cons,np->net_ring->tx_prod,np->net_ring->tx_event,
    1.16 -	 test_bit(__LINK_STATE_XOFF, &dev->state));
    1.17 +    struct net_device *dev = (struct net_device *)dev_id;
    1.18 +    struct net_private *np = dev->priv;
    1.19 +    printk(KERN_ALERT "tx_full = %d, tx_entries = %d, tx_idx = %d,"
    1.20 +           " tx_cons = %d, tx_prod = %d, tx_event = %d, state=%d\n",
    1.21 +           np->tx_full, atomic_read(&np->tx_entries), np->tx_idx, 
    1.22 +           np->net_ring->tx_cons, np->net_ring->tx_prod, 
    1.23 +           np->net_ring->tx_event,
    1.24 +           test_bit(__LINK_STATE_XOFF, &dev->state));
    1.25  }
    1.26  
    1.27  
    1.28 @@ -134,10 +136,13 @@ static int network_open(struct net_devic
    1.29          goto fail;
    1.30      }
    1.31  
    1.32 -#if 1
    1.33 -    request_irq( _EVENT_DEBUG, dbg_network_int, SA_SHIRQ, "debug", dev);    
    1.34 -#endif
    1.35 -
    1.36 +    error = request_irq(_EVENT_DEBUG, dbg_network_int, SA_SHIRQ,
    1.37 +                        "debug", dev);
    1.38 +    if ( error )
    1.39 +    {
    1.40 +        printk(KERN_WARNING "%s: Non-fatal error -- no debug interrupt\n",
    1.41 +               dev->name);
    1.42 +    }
    1.43  
    1.44      printk("XenoLinux Virtual Network Driver installed as %s\n", dev->name);
    1.45  
    1.46 @@ -163,17 +168,27 @@ static void network_tx_buf_gc(struct net
    1.47      struct net_private *np = dev->priv;
    1.48      struct sk_buff *skb;
    1.49      unsigned long flags;
    1.50 +    unsigned int cons;
    1.51  
    1.52      spin_lock_irqsave(&np->tx_lock, flags);
    1.53  
    1.54 -    for ( i = np->tx_idx; i != np->net_ring->tx_cons; i = TX_RING_INC(i) )
    1.55 -    {
    1.56 -        skb = np->tx_skb_ring[i];
    1.57 -        dev_kfree_skb_any(skb);
    1.58 -        atomic_dec(&np->tx_entries);
    1.59 +    do {
    1.60 +        cons = np->net_ring->tx_cons;
    1.61 +
    1.62 +        for ( i = np->tx_idx; i != cons; i = TX_RING_INC(i) )
    1.63 +        {
    1.64 +            skb = np->tx_skb_ring[i];
    1.65 +            dev_kfree_skb_any(skb);
    1.66 +            atomic_dec(&np->tx_entries);
    1.67 +        }
    1.68 +        
    1.69 +        np->tx_idx = i;
    1.70 +        
    1.71 +        /* Set a new event, then check for race with update of tx_cons. */
    1.72 +        np->net_ring->tx_event = TX_RING_INC(cons);
    1.73 +        smp_mb();
    1.74      }
    1.75 -
    1.76 -    np->tx_idx = i;
    1.77 +    while ( cons != np->net_ring->tx_cons );
    1.78  
    1.79      if ( np->tx_full && (atomic_read(&np->tx_entries) < TX_MAX_ENTRIES) )
    1.80      {
    1.81 @@ -278,17 +293,9 @@ static int network_start_xmit(struct sk_
    1.82      {
    1.83          np->tx_full = 1;
    1.84          netif_stop_queue(dev);
    1.85 -        np->net_ring->tx_event = 
    1.86 -            TX_RING_ADD(np->tx_idx, atomic_read(&np->tx_entries) >> 1);
    1.87 -    }
    1.88 -    else
    1.89 -    {
    1.90 -        /* Avoid unnecessary tx interrupts. */
    1.91 -        np->net_ring->tx_event = np->net_ring->tx_prod;
    1.92      }
    1.93      spin_unlock_irq(&np->tx_lock);
    1.94  
    1.95 -    /* Must do this after setting tx_event: race with updates of tx_cons. */
    1.96      network_tx_buf_gc(dev);
    1.97  
    1.98      HYPERVISOR_net_update();