Krishna Kumar wrote:
> E1000: Implement batching capability (ported thanks to changes taken from
>       Jamal).
> 
> Signed-off-by: Krishna Kumar <[EMAIL PROTECTED]>


this doesn't apply anymore and it would help if you could re-spin this for 
e1000e.
I don't know what the status for merging of the batched xmit patches is right 
now
but it would help if you could rewrite them against e1000e, which I assume is 
what
most people want to test with. There are also significant changes upstream right
now in jgarzik/netdev-2.6 #upstream...

I'm still very interested in these patches BTW.

Auke



> ---
>  e1000_main.c |  104 
> ++++++++++++++++++++++++++++++++++++++++++-----------------
>  1 files changed, 75 insertions(+), 29 deletions(-)
> 
> diff -ruNp org/drivers/net/e1000/e1000_main.c 
> new/drivers/net/e1000/e1000_main.c
> --- org/drivers/net/e1000/e1000_main.c        2007-09-14 10:30:57.000000000 
> +0530
> +++ new/drivers/net/e1000/e1000_main.c        2007-09-14 10:31:02.000000000 
> +0530
> @@ -990,7 +990,7 @@ e1000_probe(struct pci_dev *pdev,
>       if (pci_using_dac)
>               netdev->features |= NETIF_F_HIGHDMA;
>  
> -     netdev->features |= NETIF_F_LLTX;
> +     netdev->features |= NETIF_F_LLTX | NETIF_F_BATCH_SKBS;
>  
>       adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
>  
> @@ -3092,6 +3092,17 @@ e1000_tx_map(struct e1000_adapter *adapt
>       return count;
>  }
>  
> +static void e1000_kick_DMA(struct e1000_adapter *adapter,
> +                        struct e1000_tx_ring *tx_ring, int i)
> +{
> +     wmb();
> +
> +     writel(i, adapter->hw.hw_addr + tx_ring->tdt);
> +     /* we need this if more than one processor can write to our tail
> +      * at a time, it syncronizes IO on IA64/Altix systems */
> +     mmiowb();
> +}
> +
>  static void
>  e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
>                 int tx_flags, int count)
> @@ -3138,13 +3149,7 @@ e1000_tx_queue(struct e1000_adapter *ada
>        * know there are new descriptors to fetch.  (Only
>        * applicable for weak-ordered memory model archs,
>        * such as IA-64). */
> -     wmb();
> -
>       tx_ring->next_to_use = i;
> -     writel(i, adapter->hw.hw_addr + tx_ring->tdt);
> -     /* we need this if more than one processor can write to our tail
> -      * at a time, it syncronizes IO on IA64/Altix systems */
> -     mmiowb();
>  }
>  
>  /**
> @@ -3251,22 +3256,23 @@ static int e1000_maybe_stop_tx(struct ne
>  }
>  
>  #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
> +
> +#define NETDEV_TX_DROPPED    -5
> +
>  static int
> -e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
> +e1000_prep_queue_frame(struct sk_buff *skb, struct net_device *netdev)
>  {
>       struct e1000_adapter *adapter = netdev_priv(netdev);
>       struct e1000_tx_ring *tx_ring;
>       unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
>       unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
>       unsigned int tx_flags = 0;
> -     unsigned int len = skb->len;
> -     unsigned long flags;
> -     unsigned int nr_frags = 0;
> -     unsigned int mss = 0;
> +     unsigned int len = skb->len - skb->data_len;
> +     unsigned int nr_frags;
> +     unsigned int mss;
>       int count = 0;
>       int tso;
>       unsigned int f;
> -     len -= skb->data_len;
>  
>       /* This goes back to the question of how to logically map a tx queue
>        * to a flow.  Right now, performance is impacted slightly negatively
> @@ -3276,7 +3282,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
>  
>       if (unlikely(skb->len <= 0)) {
>               dev_kfree_skb_any(skb);
> -             return NETDEV_TX_OK;
> +             return NETDEV_TX_DROPPED;
>       }
>  
>       /* 82571 and newer doesn't need the workaround that limited descriptor
> @@ -3322,7 +3328,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
>                                       DPRINTK(DRV, ERR,
>                                               "__pskb_pull_tail failed.\n");
>                                       dev_kfree_skb_any(skb);
> -                                     return NETDEV_TX_OK;
> +                                     return NETDEV_TX_DROPPED;
>                               }
>                               len = skb->len - skb->data_len;
>                               break;
> @@ -3366,22 +3372,15 @@ e1000_xmit_frame(struct sk_buff *skb, st
>           (adapter->hw.mac_type == e1000_82573))
>               e1000_transfer_dhcp_info(adapter, skb);
>  
> -     if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
> -             /* Collision - tell upper layer to requeue */
> -             return NETDEV_TX_LOCKED;
> -
>       /* need: count + 2 desc gap to keep tail from touching
>        * head, otherwise try next time */
> -     if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
> -             spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
> +     if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
>               return NETDEV_TX_BUSY;
> -     }
>  
>       if (unlikely(adapter->hw.mac_type == e1000_82547)) {
>               if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
>                       netif_stop_queue(netdev);
>                       mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
> -                     spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
>                       return NETDEV_TX_BUSY;
>               }
>       }
> @@ -3396,8 +3395,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
>       tso = e1000_tso(adapter, tx_ring, skb);
>       if (tso < 0) {
>               dev_kfree_skb_any(skb);
> -             spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
> -             return NETDEV_TX_OK;
> +             return NETDEV_TX_DROPPED;
>       }
>  
>       if (likely(tso)) {
> @@ -3416,13 +3414,61 @@ e1000_xmit_frame(struct sk_buff *skb, st
>                      e1000_tx_map(adapter, tx_ring, skb, first,
>                                   max_per_txd, nr_frags, mss));
>  
> -     netdev->trans_start = jiffies;
> +     return NETDEV_TX_OK;
> +}
> +
> +static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
> +{
> +     struct e1000_adapter *adapter = netdev_priv(netdev);
> +     struct e1000_tx_ring *tx_ring = adapter->tx_ring;
> +     struct sk_buff_head *blist;
> +     int ret, skbs_done = 0;
> +     unsigned long flags;
> +
> +     if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {
> +             /* Collision - tell upper layer to requeue */
> +             return NETDEV_TX_LOCKED;
> +     }
>  
> -     /* Make sure there is space in the ring for the next send. */
> -     e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
> +     blist = netdev->skb_blist;
> +
> +     if (!skb || (blist && skb_queue_len(blist))) {
> +             /*
> +              * Either batching xmit call, or single skb case but there are
> +              * skbs already in the batch list from previous failure to
> +              * xmit - send the earlier skbs first to avoid out of order.
> +              */
> +             if (skb)
> +                     __skb_queue_tail(blist, skb);
> +             skb = __skb_dequeue(blist);
> +     } else {
> +             blist = NULL;
> +     }
> +
> +     do {
> +             ret = e1000_prep_queue_frame(skb, netdev);
> +             if (likely(ret == NETDEV_TX_OK))
> +                     skbs_done++;
> +             else {
> +                     if (ret == NETDEV_TX_BUSY) {
> +                             if (blist)
> +                                     __skb_queue_head(blist, skb);
> +                             break;
> +                     }
> +                     /* skb dropped, not a TX error */
> +                     ret = NETDEV_TX_OK;
> +             }
> +     } while (blist && (skb = __skb_dequeue(blist)) != NULL);
> +
> +     if (skbs_done) {
> +             e1000_kick_DMA(adapter, tx_ring, adapter->tx_ring->next_to_use);
> +             netdev->trans_start = jiffies;
> +             /* Make sure there is space in the ring for the next send. */
> +             e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
> +     }
>  
>       spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
> -     return NETDEV_TX_OK;
> +     return ret;
>  }
>  
>  /**
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to [EMAIL PROTECTED]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to