On 9/15/23 11:00, Prasurjya Rohan saikia - I73664 wrote: > From: Prasurjya Rohan Saikia <prasurjya.rohansaikia@xxxxxxxxxxxxx> > > Add an algorithm to backoff the Tx Task when low memory scenario is > triggered at firmware. During high data transfer from host, the firmware > runs out of VMM memory, which is used to hold the frames from the host. > So, adding the flow control delays the transmit from host side when > there is not enough space to accommodate frames in firmware side. > > Signed-off-by: Prasurjya Rohan Saikia <prasurjya.rohansaikia@xxxxxxxxxxxxx> Acked-by: Ajay Singh <ajay.kathat@xxxxxxxxxxxxx> > --- > v3 -> v4: As per review comments, replaced > schedule_timeout_interruptible() by msleep_interruptible(). > > v2 -> v3: Replaced schedule_timeout() by > schedule_timeout_interruptible(). > > v1 -> v2: Removed the unused `timeout` variable. > --- > .../net/wireless/microchip/wilc1000/netdev.c | 20 +++++++++++++++---- > .../net/wireless/microchip/wilc1000/netdev.h | 2 ++ > 2 files changed, 18 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c > index e9f59de31b0b..91d71e0f7ef2 100644 > --- a/drivers/net/wireless/microchip/wilc1000/netdev.c > +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c > @@ -148,8 +148,8 @@ static int wilc_txq_task(void *vp) > > complete(&wl->txq_thread_started); > while (1) { > - wait_for_completion(&wl->txq_event); > - > + if (wait_for_completion_interruptible(&wl->txq_event)) > + continue; > if (wl->close) { > complete(&wl->txq_thread_started); > > @@ -166,12 +166,24 @@ static int wilc_txq_task(void *vp) > srcu_idx = srcu_read_lock(&wl->srcu); > list_for_each_entry_rcu(ifc, &wl->vif_list, > list) { > - if (ifc->mac_opened && ifc->ndev) > + if (ifc->mac_opened && > + netif_queue_stopped(ifc->ndev)) > netif_wake_queue(ifc->ndev); > } > srcu_read_unlock(&wl->srcu, srcu_idx); > } > - } while (ret == WILC_VMM_ENTRY_FULL_RETRY && !wl->close); > + if (ret != WILC_VMM_ENTRY_FULL_RETRY) > + break; > + /* Back off TX task from sending packets for some time. > + * msleep_interruptible will allow RX task to run and > + * free buffers. TX task will be in TASK_INTERRUPTIBLE > + * state which will put the thread back to CPU running > + * queue when it's signaled even if the timeout isn't > + * elapsed. This gives faster chance for reserved SK > + * buffers to be free. > + */ > + msleep_interruptible(TX_BACKOFF_WEIGHT_MS); > + } while (!wl->close); > } > return 0; > } > diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.h b/drivers/net/wireless/microchip/wilc1000/netdev.h > index bb1a315a7b7e..aafe3dc44ac6 100644 > --- a/drivers/net/wireless/microchip/wilc1000/netdev.h > +++ b/drivers/net/wireless/microchip/wilc1000/netdev.h > @@ -27,6 +27,8 @@ > #define TCP_ACK_FILTER_LINK_SPEED_THRESH 54 > #define DEFAULT_LINK_SPEED 72 > > +#define TX_BACKOFF_WEIGHT_MS 1 > + > struct wilc_wfi_stats { > unsigned long rx_packets; > unsigned long tx_packets;