On Mon, Jun 26, 2023 at 07:50:44PM +0530, Praveen Kumar wrote: > On 6/26/2023 2:48 PM, souradeep chakrabarti wrote: > > From: Souradeep Chakrabarti <schakrabarti@xxxxxxxxxxxxxxxxxxx> > > > > This patch addresses the VF unload issue, where mana_dealloc_queues() > > gets stuck in infinite while loop, because of host unresponsiveness. > > It adds a timeout in the while loop, to fix it. > > > > Fixes: ca9c54d2d6a5ab2430c4eda364c77125d62e5e0f (net: mana: Add a driver for > > Microsoft Azure Network Adapter) > > Signed-off-by: Souradeep Chakrabarti <schakrabarti@xxxxxxxxxxxxxxxxxxx> > > --- > > V2 -> V3: > > * Splitted the patch in two parts. > > * Removed the unnecessary braces from mana_dealloc_queues(). > > --- > > drivers/net/ethernet/microsoft/mana/mana_en.c | 19 +++++++++++++++++-- > > 1 file changed, 17 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c > > index d907727c7b7a..cb5c43c3c47e 100644 > > --- a/drivers/net/ethernet/microsoft/mana/mana_en.c > > +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c > > @@ -2329,7 +2329,10 @@ static int mana_dealloc_queues(struct net_device *ndev) > > { > > struct mana_port_context *apc = netdev_priv(ndev); > > struct gdma_dev *gd = apc->ac->gdma_dev; > > + unsigned long timeout; > > struct mana_txq *txq; > > + struct sk_buff *skb; > > + struct mana_cq *cq; > > int i, err; > > > > if (apc->port_is_up) > > @@ -2348,13 +2351,25 @@ static int mana_dealloc_queues(struct net_device *ndev) > > * > > * Drain all the in-flight TX packets > > */ > > + > > + timeout = jiffies + 120 * HZ; > > for (i = 0; i < apc->num_queues; i++) { > > txq = &apc->tx_qp[i].txq; > > - > > - while (atomic_read(&txq->pending_sends) > 0) > > + while (atomic_read(&txq->pending_sends) > 0 && > > + time_before(jiffies, timeout)) > > usleep_range(1000, 2000); > > } > > > > + for (i = 0; i < apc->num_queues; i++) { > > + txq = &apc->tx_qp[i].txq; > > + cq = &apc->tx_qp[i].tx_cq; > > + while (atomic_read(&txq->pending_sends)) { > > + skb = skb_dequeue(&txq->pending_skbs); > > + mana_unmap_skb(skb, apc); > > + napi_consume_skb(skb, cq->budget); > > + atomic_sub(1, &txq->pending_sends); > > + } > > + } > > Can we combine these 2 loops into 1 something like this ? > > for (i = 0; i < apc->num_queues; i++) { > txq = &apc->tx_qp[i].txq; > cq = &apc->tx_qp[i].tx_cq; > while (atomic_read(&txq->pending_sends)) { > if (time_before(jiffies, timeout)) { > usleep_range(1000, 2000); > } else { > skb = skb_dequeue(&txq->pending_skbs); > mana_unmap_skb(skb, apc); > napi_consume_skb(skb, cq->budget); > atomic_sub(1, &txq->pending_sends); > } > } > } We should free up the skbs only after timeout has happened or after all the queues are looped. > > /* We're 100% sure the queues can no longer be woken up, because > > * we're sure now mana_poll_tx_cq() can't be running. > > */