amd-xgbe: handle the corner-case during tx completion
[ Upstream commit 7121205d5330c6a3cb3379348886d47c77b78d06 ]
The existing implementation uses software logic to accumulate tx
completions until the specified time (1ms) is met and then poll them.
However, there exists a tiny gap which leads to a race between
resetting and checking the tx_activate flag. Due to this the tx
completions are not reported to upper layer and tx queue timeout
kicks-in restarting the device.
To address this, introduce a tx cleanup mechanism as part of the
periodic maintenance process.
Fixes: c5aa9e3b81
("amd-xgbe: Initial AMD 10GbE platform driver")
Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
a2e868ad07
commit
b7c9e8c038
@@ -682,10 +682,24 @@ static void xgbe_service(struct work_struct *work)
|
|||||||
static void xgbe_service_timer(struct timer_list *t)
|
static void xgbe_service_timer(struct timer_list *t)
|
||||||
{
|
{
|
||||||
struct xgbe_prv_data *pdata = from_timer(pdata, t, service_timer);
|
struct xgbe_prv_data *pdata = from_timer(pdata, t, service_timer);
|
||||||
|
struct xgbe_channel *channel;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
queue_work(pdata->dev_workqueue, &pdata->service_work);
|
queue_work(pdata->dev_workqueue, &pdata->service_work);
|
||||||
|
|
||||||
mod_timer(&pdata->service_timer, jiffies + HZ);
|
mod_timer(&pdata->service_timer, jiffies + HZ);
|
||||||
|
|
||||||
|
if (!pdata->tx_usecs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < pdata->channel_count; i++) {
|
||||||
|
channel = pdata->channel[i];
|
||||||
|
if (!channel->tx_ring || channel->tx_timer_active)
|
||||||
|
break;
|
||||||
|
channel->tx_timer_active = 1;
|
||||||
|
mod_timer(&channel->tx_timer,
|
||||||
|
jiffies + usecs_to_jiffies(pdata->tx_usecs));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xgbe_init_timers(struct xgbe_prv_data *pdata)
|
static void xgbe_init_timers(struct xgbe_prv_data *pdata)
|
||||||
|
Reference in New Issue
Block a user