[OpenWrt-Devel] [PATCH] [ 4/5] ramips: add xmit_more support

Mingyu Li igvtee at gmail.com
Thu Jun 18 06:03:39 EDT 2015


Dear Sir.

have any suggestion?

Best Regards.

2015-06-05 18:09 GMT+08:00 Mingyu Li <igvtee at gmail.com>:

> this feature i reference tg3.c driver at function tg3_start_xmit.
> it says therer is a small possibility that start_xmit will miss it
> and cause the queue to be stopped forever.
>
> below is the tg3 drivers code
> === function tg3_tx ===
>         tnapi->tx_cons = sw_idx;
>
>         /* Need to make the tx_cons update visible to tg3_start_xmit()
>          * before checking for netif_queue_stopped().  Without the
>          * memory barrier, there is a small possibility that
> tg3_start_xmit()
>          * will miss it and cause the queue to be stopped forever.
>          */
>         smp_mb();
>
>         if (unlikely(netif_tx_queue_stopped(txq) &&
>                      (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))))
> {
>                 __netif_tx_lock(txq, smp_processor_id());
>                 if (netif_tx_queue_stopped(txq) &&
>                     (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))
>                         netif_tx_wake_queue(txq);
>                 __netif_tx_unlock(txq);
>         }
>
> === tg3_start_xmit ===
>         budget = tg3_tx_avail(tnapi);
>
>         /* We are running in BH disabled context with netif_tx_lock
>          * and TX reclaim runs via tp->napi.poll inside of a software
>          * interrupt.  Furthermore, IRQ processing runs lockless so we have
>          * no IRQ context deadlocks to worry about either.  Rejoice!
>          */
>         if (unlikely(budget <= (skb_shinfo(skb)->nr_frags + 1))) {
>                 if (!netif_tx_queue_stopped(txq)) {
>                         netif_tx_stop_queue(txq);
>
>                         /* This is a hard error, log it. */
>                         netdev_err(dev,
>                                    "BUG! Tx Ring full when queue
> awake!\n");
>                 }
>                 return NETDEV_TX_BUSY;
>         }
>
>
> 2015-06-05 16:40 GMT+08:00 Felix Fietkau <nbd at openwrt.org>:
>
>> On 2015-06-02 15:06, michael lee wrote:
>> > use pktgen to verify on rt3662. can improve transmit rate.
>> > pkt_size 1500
>> > burst 1 : 807Mb/sec
>> > burst 8 : 984Mb/sec
>> >
>> > pkt_size 60
>> > burst 1 : 57Mb/sec
>> > burst 8 : 236Mb/sec
>> >
>> > Signed-off-by: michael lee <igvtee at gmail.com>
>> > ---
>> >  .../drivers/net/ethernet/ralink/ralink_soc_eth.c   | 51
>> +++++++++++++---------
>> >  .../drivers/net/ethernet/ralink/ralink_soc_eth.h   |  2 +
>> >  2 files changed, 33 insertions(+), 20 deletions(-)
>> >
>> > diff --git
>> a/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c
>> b/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c
>> > index b2304bb..4b39825 100644
>> > ---
>> a/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c
>> > +++
>> b/target/linux/ramips/files/drivers/net/ethernet/ralink/ralink_soc_eth.c
>> > @@ -337,6 +337,8 @@ static int fe_alloc_tx(struct fe_priv *priv)
>> >       struct fe_tx_ring *ring = &priv->tx_ring;
>> >
>> >       ring->tx_free_idx = 0;
>> > +     ring->tx_next_idx = 0;
>> > +     ring->tx_thresh = max((unsigned long)ring->tx_ring_size >> 2,
>> MAX_SKB_FRAGS);
>> >
>> >       ring->tx_buf = kcalloc(ring->tx_ring_size, sizeof(*ring->tx_buf),
>> >                       GFP_KERNEL);
>> > @@ -525,8 +527,16 @@ static int fe_vlan_rx_kill_vid(struct net_device
>> *dev,
>> >       return 0;
>> >  }
>> >
>> > +static inline u32 fe_empty_txd(struct fe_tx_ring *ring)
>> > +{
>> > +     barrier();
>> What is this barrier for?
>>
>> > +     return (u32)(ring->tx_ring_size -
>> > +                     ((ring->tx_next_idx - ring->tx_free_idx) &
>> > +                      (ring->tx_ring_size - 1)));
>> > +}
>> > +
>> >  static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev,
>> > -             int idx, int tx_num, struct fe_tx_ring *ring)
>> > +             int tx_num, struct fe_tx_ring *ring)
>> >  {
>> >       struct fe_priv *priv = netdev_priv(dev);
>> >       struct skb_frag_struct *frag;
>> > @@ -649,14 +659,22 @@ static int fe_tx_map_dma(struct sk_buff *skb,
>> struct net_device *dev,
>> >       netdev_sent_queue(dev, skb->len);
>> >       skb_tx_timestamp(skb);
>> >
>> > -     j = NEXT_TX_DESP_IDX(j);
>> > +     ring->tx_next_idx = NEXT_TX_DESP_IDX(j);
>> >       wmb();
>> > -     fe_reg_w32(j, FE_REG_TX_CTX_IDX0);
>> > +     if (unlikely(fe_empty_txd(ring) <= ring->tx_thresh)) {
>> > +             netif_stop_queue(dev);
>> > +             smp_mb();
>> > +             if (unlikely(fe_empty_txd(ring) > ring->tx_thresh))
>> > +                     netif_wake_queue(dev);
>> Why do that queue wake check here, when it's already being done during
>> tx cleanup.
>>
>> > +     }
>> > +
>> > +     if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) ||
>> !skb->xmit_more)
>> > +             fe_reg_w32(ring->tx_next_idx, FE_REG_TX_CTX_IDX0);
>> >
>> >       return 0;
>> >
>> >  err_dma:
>> > -     j = idx;
>> > +     j = ring->tx_next_idx;
>> >       for (i = 0; i < tx_num; i++) {
>> >               ptxd = &ring->tx_dma[j];
>> >               tx_buf = &ring->tx_buf[j];
>>
>> - Felix
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/openwrt-devel/attachments/20150618/35b9e039/attachment.htm>
-------------- next part --------------
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list