amd-xgbe: handle the corner-case during tx completion
authorRaju Rangoju <Raju.Rangoju@amd.com>
Tue, 21 Nov 2023 19:14:34 +0000 (00:44 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 3 Dec 2023 06:33:05 +0000 (07:33 +0100)
[ 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: c5aa9e3b8156 ("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>
drivers/net/ethernet/amd/xgbe/xgbe-drv.c

index 614c027..6b73648 100644 (file)
@@ -682,10 +682,24 @@ static void xgbe_service(struct work_struct *work)
 static void xgbe_service_timer(struct timer_list *t)
 {
        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);
 
        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)