From: Prasurjya Rohan Saikia <[email protected]>
Added 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 added flow control to delay the transmit from host side when there is
not enough space to accomodate frames in firmware side.
Signed-off-by: Prasurjya Rohan Saikia <[email protected]>
---
.../net/wireless/microchip/wilc1000/netdev.c | 19 ++++++++++++++++---
.../net/wireless/microchip/wilc1000/netdev.h | 2 ++
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
index e9f59de31b0b..40b34490f6ef 100644
--- a/drivers/net/wireless/microchip/wilc1000/netdev.c
+++ b/drivers/net/wireless/microchip/wilc1000/netdev.c
@@ -144,12 +144,13 @@ static int wilc_txq_task(void *vp)
{
int ret;
u32 txq_count;
+ signed long timeout;
struct wilc *wl = 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,11 +167,23 @@ 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);
}
+ if (ret != WILC_VMM_ENTRY_FULL_RETRY)
+ break;
+ /* Back off from sending packets for some time.
+ * schedule_timeout will allow RX task to run and free
+ * buffers. Setting state to TASK_INTERRUPTIBLE will
+ * put the thread back to CPU running queue when it's
+ * signaled even if 'timeout' isn't elapsed. This gives
+ * faster chance for reserved SK buffers to be freed
+ */
+ set_current_state(TASK_INTERRUPTIBLE);
+ timeout = schedule_timeout(msecs_to_jiffies(TX_BACKOFF_WEIGHT_MS));
} while (ret == WILC_VMM_ENTRY_FULL_RETRY && !wl->close);
}
return 0;
diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.h b/drivers/net/wireless/microchip/wilc1000/netdev.h
index bb1a315a7b7e..380ad38ecb64 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;
--
2.34.1
Hi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on wireless-next/main]
[also build test WARNING on wireless/main linus/master v6.5-rc5 next-20230809]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Prasurjya-Rohansaikia-microchip-com/wifi-wilc1000-Added-back-off-algorithm-to-balance-tx-queue-packets/20230811-024902
base: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
patch link: https://lore.kernel.org/r/20230810184633.94338-1-prasurjya.rohansaikia%40microchip.com
patch subject: [PATCH] wifi: wilc1000: Added back-off algorithm to balance tx queue packets.
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20230812/[email protected]/config)
compiler: sh4-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230812/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
drivers/net/wireless/microchip/wilc1000/netdev.c: In function 'wilc_txq_task':
>> drivers/net/wireless/microchip/wilc1000/netdev.c:147:21: warning: variable 'timeout' set but not used [-Wunused-but-set-variable]
147 | signed long timeout;
| ^~~~~~~
vim +/timeout +147 drivers/net/wireless/microchip/wilc1000/netdev.c
142
143 static int wilc_txq_task(void *vp)
144 {
145 int ret;
146 u32 txq_count;
> 147 signed long timeout;
148 struct wilc *wl = vp;
149
150 complete(&wl->txq_thread_started);
151 while (1) {
152 if (wait_for_completion_interruptible(&wl->txq_event))
153 continue;
154 if (wl->close) {
155 complete(&wl->txq_thread_started);
156
157 while (!kthread_should_stop())
158 schedule();
159 break;
160 }
161 do {
162 ret = wilc_wlan_handle_txq(wl, &txq_count);
163 if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) {
164 int srcu_idx;
165 struct wilc_vif *ifc;
166
167 srcu_idx = srcu_read_lock(&wl->srcu);
168 list_for_each_entry_rcu(ifc, &wl->vif_list,
169 list) {
170 if (ifc->mac_opened &&
171 netif_queue_stopped(ifc->ndev))
172 netif_wake_queue(ifc->ndev);
173 }
174 srcu_read_unlock(&wl->srcu, srcu_idx);
175 }
176 if (ret != WILC_VMM_ENTRY_FULL_RETRY)
177 break;
178 /* Back off from sending packets for some time.
179 * schedule_timeout will allow RX task to run and free
180 * buffers. Setting state to TASK_INTERRUPTIBLE will
181 * put the thread back to CPU running queue when it's
182 * signaled even if 'timeout' isn't elapsed. This gives
183 * faster chance for reserved SK buffers to be freed
184 */
185 set_current_state(TASK_INTERRUPTIBLE);
186 timeout = schedule_timeout(msecs_to_jiffies(TX_BACKOFF_WEIGHT_MS));
187 } while (ret == WILC_VMM_ENTRY_FULL_RETRY && !wl->close);
188 }
189 return 0;
190 }
191
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki