From 0cc8a490ce9adb716da0bf09304bf2efa4fe0d29 Mon Sep 17 00:00:00 2001 From: Karthik Kantamneni Date: Tue, 23 Nov 2021 15:56:00 +0530 Subject: [PATCH] qcacld-3.0: Control netif sub queues with sub queue pause mask Currently global pause mask is used for controlling individual AC based sub queues and even all the network queues, due to this mask is set/reset improperly which is not giving actual global queue status representation. To avoid this introduced new sub queue mask which is used while controlling individual network sub queues and global mask is over for overall network queues. Change-Id: I6632a1831cbea84c23441dbb67473c94b487109a CRs-Fixed: 3081060 --- core/hdd/inc/wlan_hdd_main.h | 2 + core/hdd/src/wlan_hdd_tx_rx.c | 101 ++++++++++++++++++++++++---------- 2 files changed, 73 insertions(+), 30 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index e0b279b6f7f8..a129d5903766 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1451,6 +1452,7 @@ struct hdd_adapter { /* BITMAP indicating pause reason */ uint32_t pause_map; + uint32_t subqueue_pause_map; spinlock_t pause_map_lock; qdf_time_t start_time; qdf_time_t last_time; diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index d685268e1f7f..645b40897d31 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -2760,6 +2760,7 @@ const char *hdd_action_type_to_string(enum netif_action_type action) CASE_RETURN_STRING(WLAN_NETIF_VO_QUEUE_OFF); CASE_RETURN_STRING(WLAN_NETIF_VI_QUEUE_ON); CASE_RETURN_STRING(WLAN_NETIF_VI_QUEUE_OFF); + CASE_RETURN_STRING(WLAN_NETIF_BE_BK_QUEUE_ON); CASE_RETURN_STRING(WLAN_NETIF_BE_BK_QUEUE_OFF); CASE_RETURN_STRING(WLAN_WAKE_NON_PRIORITY_QUEUE); CASE_RETURN_STRING(WLAN_STOP_NON_PRIORITY_QUEUE); @@ -2790,6 +2791,7 @@ static void wlan_hdd_update_queue_oper_stats(struct hdd_adapter *adapter, case WLAN_START_ALL_NETIF_QUEUE: case WLAN_WAKE_ALL_NETIF_QUEUE: case WLAN_START_ALL_NETIF_QUEUE_N_CARRIER: + case WLAN_NETIF_BE_BK_QUEUE_ON: case WLAN_NETIF_VI_QUEUE_ON: case WLAN_NETIF_VO_QUEUE_ON: case WLAN_NETIF_PRIORITY_QUEUE_ON: @@ -3021,65 +3023,99 @@ void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter, case WLAN_NETIF_PRIORITY_QUEUE_ON: spin_lock_bh(&adapter->pause_map_lock); - temp_map = adapter->pause_map; - adapter->pause_map &= ~(1 << reason); - netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO); - wlan_hdd_update_pause_time(adapter, temp_map); + if (reason == WLAN_DATA_FLOW_CTRL_PRI) { + temp_map = adapter->subqueue_pause_map; + adapter->subqueue_pause_map &= ~(1 << reason); + } else { + temp_map = adapter->pause_map; + adapter->pause_map &= ~(1 << reason); + } + if (!adapter->pause_map) { + netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO); + wlan_hdd_update_pause_time(adapter, temp_map); + } spin_unlock_bh(&adapter->pause_map_lock); break; case WLAN_NETIF_PRIORITY_QUEUE_OFF: spin_lock_bh(&adapter->pause_map_lock); - netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO); - wlan_hdd_update_txq_timestamp(adapter->dev); - wlan_hdd_update_unpause_time(adapter); - adapter->pause_map |= (1 << reason); + if (!adapter->pause_map) { + netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO); + wlan_hdd_update_txq_timestamp(adapter->dev); + wlan_hdd_update_unpause_time(adapter); + } + if (reason == WLAN_DATA_FLOW_CTRL_PRI) + adapter->subqueue_pause_map |= (1 << reason); + else + adapter->pause_map |= (1 << reason); spin_unlock_bh(&adapter->pause_map_lock); break; case WLAN_NETIF_BE_BK_QUEUE_OFF: spin_lock_bh(&adapter->pause_map_lock); - netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK); - netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE); - wlan_hdd_update_txq_timestamp(adapter->dev); - wlan_hdd_update_unpause_time(adapter); - adapter->pause_map |= (1 << reason); + if (!adapter->pause_map) { + netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK); + netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE); + wlan_hdd_update_txq_timestamp(adapter->dev); + wlan_hdd_update_unpause_time(adapter); + } + adapter->subqueue_pause_map |= (1 << reason); + spin_unlock_bh(&adapter->pause_map_lock); + break; + + case WLAN_NETIF_BE_BK_QUEUE_ON: + spin_lock_bh(&adapter->pause_map_lock); + temp_map = adapter->subqueue_pause_map; + adapter->subqueue_pause_map &= ~(1 << reason); + if (!adapter->pause_map) { + netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_BK); + netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_BE); + wlan_hdd_update_pause_time(adapter, temp_map); + } spin_unlock_bh(&adapter->pause_map_lock); break; case WLAN_NETIF_VI_QUEUE_OFF: spin_lock_bh(&adapter->pause_map_lock); - netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI); - wlan_hdd_update_txq_timestamp(adapter->dev); - wlan_hdd_update_unpause_time(adapter); - adapter->pause_map |= (1 << reason); + if (!adapter->pause_map) { + netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI); + wlan_hdd_update_txq_timestamp(adapter->dev); + wlan_hdd_update_unpause_time(adapter); + } + adapter->subqueue_pause_map |= (1 << reason); spin_unlock_bh(&adapter->pause_map_lock); break; case WLAN_NETIF_VI_QUEUE_ON: spin_lock_bh(&adapter->pause_map_lock); - temp_map = adapter->pause_map; - adapter->pause_map &= ~(1 << reason); - netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VI); - wlan_hdd_update_pause_time(adapter, temp_map); + temp_map = adapter->subqueue_pause_map; + adapter->subqueue_pause_map &= ~(1 << reason); + if (!adapter->pause_map) { + netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VI); + wlan_hdd_update_pause_time(adapter, temp_map); + } spin_unlock_bh(&adapter->pause_map_lock); break; case WLAN_NETIF_VO_QUEUE_OFF: spin_lock_bh(&adapter->pause_map_lock); - netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO); - wlan_hdd_update_txq_timestamp(adapter->dev); - wlan_hdd_update_unpause_time(adapter); - adapter->pause_map |= (1 << reason); + if (!adapter->pause_map) { + netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO); + wlan_hdd_update_txq_timestamp(adapter->dev); + wlan_hdd_update_unpause_time(adapter); + } + adapter->subqueue_pause_map |= (1 << reason); spin_unlock_bh(&adapter->pause_map_lock); break; case WLAN_NETIF_VO_QUEUE_ON: spin_lock_bh(&adapter->pause_map_lock); - temp_map = adapter->pause_map; - adapter->pause_map &= ~(1 << reason); - netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VO); - wlan_hdd_update_pause_time(adapter, temp_map); + temp_map = adapter->subqueue_pause_map; + adapter->subqueue_pause_map &= ~(1 << reason); + if (!adapter->pause_map) { + netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VO); + wlan_hdd_update_pause_time(adapter, temp_map); + } spin_unlock_bh(&adapter->pause_map_lock); break; @@ -3161,7 +3197,12 @@ void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter, adapter->queue_oper_history[index].time = qdf_system_ticks(); adapter->queue_oper_history[index].netif_action = action; adapter->queue_oper_history[index].netif_reason = reason; - adapter->queue_oper_history[index].pause_map = adapter->pause_map; + if (reason >= WLAN_DATA_FLOW_CTRL_BE_BK) + adapter->queue_oper_history[index].pause_map = + adapter->subqueue_pause_map; + else + adapter->queue_oper_history[index].pause_map = + adapter->pause_map; txq_hist_ptr = &adapter->queue_oper_history[index];