amd-xgbe: Remove Tx coalescing
authorLendacky, Thomas <Thomas.Lendacky@amd.com>
Fri, 20 Mar 2015 16:50:28 +0000 (11:50 -0500)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Mar 2015 20:33:57 +0000 (16:33 -0400)
The Tx coalescing support in the driver was a software implementation
for something lacking in the hardware. Using hrtimers, the idea was to
trigger a timer interrupt after having queued a packet for transmit.
Unfortunately, as the timer value was lowered, the timer expired before
the hardware actually did the transmit and so it was racey and resulted
in unnecessary interrupts.

Remove the Tx coalescing support and hrtimer and replace with a Tx timer
that is used as a reclaim timer in case of inactivity.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
drivers/net/ethernet/amd/xgbe/xgbe.h

index e165d069d6b00064cd4480c93dd8fd7755ab4513..80dd7a92f3574b5d09f04d077def087016c136e0 100644 (file)
@@ -1367,12 +1367,11 @@ static void xgbe_tx_start_xmit(struct xgbe_channel *channel,
        XGMAC_DMA_IOWRITE(channel, DMA_CH_TDTR_LO,
                          lower_32_bits(rdata->rdesc_dma));
 
-       /* Start the Tx coalescing timer */
+       /* Start the Tx timer */
        if (pdata->tx_usecs && !channel->tx_timer_active) {
                channel->tx_timer_active = 1;
-               hrtimer_start(&channel->tx_timer,
-                             ktime_set(0, pdata->tx_usecs * NSEC_PER_USEC),
-                             HRTIMER_MODE_REL);
+               mod_timer(&channel->tx_timer,
+                         jiffies + usecs_to_jiffies(pdata->tx_usecs));
        }
 
        ring->tx.xmit_more = 0;
index ef4625e4897674d588c9a30b955b95669640b766..122a631c4ce0c661e58412875ce203c87822502e 100644 (file)
@@ -411,11 +411,9 @@ static irqreturn_t xgbe_dma_isr(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
+static void xgbe_tx_timer(unsigned long data)
 {
-       struct xgbe_channel *channel = container_of(timer,
-                                                   struct xgbe_channel,
-                                                   tx_timer);
+       struct xgbe_channel *channel = (struct xgbe_channel *)data;
        struct xgbe_prv_data *pdata = channel->pdata;
        struct napi_struct *napi;
 
@@ -437,8 +435,6 @@ static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
        channel->tx_timer_active = 0;
 
        DBGPR("<--xgbe_tx_timer\n");
-
-       return HRTIMER_NORESTART;
 }
 
 static void xgbe_init_tx_timers(struct xgbe_prv_data *pdata)
@@ -454,9 +450,8 @@ static void xgbe_init_tx_timers(struct xgbe_prv_data *pdata)
                        break;
 
                DBGPR("  %s adding tx timer\n", channel->name);
-               hrtimer_init(&channel->tx_timer, CLOCK_MONOTONIC,
-                            HRTIMER_MODE_REL);
-               channel->tx_timer.function = xgbe_tx_timer;
+               setup_timer(&channel->tx_timer, xgbe_tx_timer,
+                           (unsigned long)channel);
        }
 
        DBGPR("<--xgbe_init_tx_timers\n");
@@ -475,8 +470,7 @@ static void xgbe_stop_tx_timers(struct xgbe_prv_data *pdata)
                        break;
 
                DBGPR("  %s deleting tx timer\n", channel->name);
-               channel->tx_timer_active = 0;
-               hrtimer_cancel(&channel->tx_timer);
+               del_timer_sync(&channel->tx_timer);
        }
 
        DBGPR("<--xgbe_stop_tx_timers\n");
index 43e5571fe858e5ee87b273ff6fdf73c7708e70b5..376d6a529ea109490f2f80a384586b611db15806 100644 (file)
@@ -388,7 +388,6 @@ static int xgbe_get_coalesce(struct net_device *netdev,
        ec->rx_coalesce_usecs = hw_if->riwt_to_usec(pdata, riwt);
        ec->rx_max_coalesced_frames = pdata->rx_frames;
 
-       ec->tx_coalesce_usecs = pdata->tx_usecs;
        ec->tx_max_coalesced_frames = pdata->tx_frames;
 
        DBGPR("<--xgbe_get_coalesce\n");
@@ -402,13 +401,14 @@ static int xgbe_set_coalesce(struct net_device *netdev,
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
        struct xgbe_hw_if *hw_if = &pdata->hw_if;
        unsigned int rx_frames, rx_riwt, rx_usecs;
-       unsigned int tx_frames, tx_usecs;
+       unsigned int tx_frames;
 
        DBGPR("-->xgbe_set_coalesce\n");
 
        /* Check for not supported parameters  */
        if ((ec->rx_coalesce_usecs_irq) ||
            (ec->rx_max_coalesced_frames_irq) ||
+           (ec->tx_coalesce_usecs) ||
            (ec->tx_coalesce_usecs_irq) ||
            (ec->tx_max_coalesced_frames_irq) ||
            (ec->stats_block_coalesce_usecs) ||
@@ -457,7 +457,6 @@ static int xgbe_set_coalesce(struct net_device *netdev,
                return -EINVAL;
        }
 
-       tx_usecs = ec->tx_coalesce_usecs;
        tx_frames = ec->tx_max_coalesced_frames;
 
        /* Check the bounds of values for Tx */
@@ -471,7 +470,6 @@ static int xgbe_set_coalesce(struct net_device *netdev,
        pdata->rx_frames = rx_frames;
        hw_if->config_rx_coalesce(pdata);
 
-       pdata->tx_usecs = tx_usecs;
        pdata->tx_frames = tx_frames;
        hw_if->config_tx_coalesce(pdata);
 
index bfe11fb06036b7b86c563209a51da821f391e4fe..72b8f27e7216d599450231891c3015fb6d6b5aa2 100644 (file)
         ((_idx) & ((_ring)->rdesc_count - 1)))
 
 /* Default coalescing parameters */
-#define XGMAC_INIT_DMA_TX_USECS                50
+#define XGMAC_INIT_DMA_TX_USECS                1000
 #define XGMAC_INIT_DMA_TX_FRAMES       25
 
 #define XGMAC_MAX_DMA_RIWT             0xff
@@ -410,7 +410,7 @@ struct xgbe_channel {
        unsigned int saved_ier;
 
        unsigned int tx_timer_active;
-       struct hrtimer tx_timer;
+       struct timer_list tx_timer;
 
        struct xgbe_ring *tx_ring;
        struct xgbe_ring *rx_ring;