Skip to content

Commit

Permalink
amd-xgbe: Remove Tx coalescing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Lendacky, Thomas authored and David S. Miller committed Mar 20, 2015
1 parent 386d325 commit c635eaa
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 21 deletions.
7 changes: 3 additions & 4 deletions drivers/net/ethernet/amd/xgbe/xgbe-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
16 changes: 5 additions & 11 deletions drivers/net/ethernet/amd/xgbe/xgbe-drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
Expand All @@ -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");
Expand All @@ -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");
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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) ||
Expand Down Expand Up @@ -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 */
Expand All @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/amd/xgbe/xgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@
((_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
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit c635eaa

Please sign in to comment.