qcacld-3.0: Add a NAPI mode for roaming
Add a new mode with a pair of new NAPI events, NAPI_EVT_USR_SERIAL
and NAPI_EVT_USR_NORMAL, which allows client force NAPI to move all
instances onto the same CPU and peg them there (blacklist); and
to move back to normal mode of operation.
This part implements the HDD portion. Goes with the corresponding
HIF code.
Change-Id: I4c45d18348ef27d8814c5d0321d1fd13c96fff34
CRs-Fixed: 1078976
diff --git a/core/hdd/inc/wlan_hdd_napi.h b/core/hdd/inc/wlan_hdd_napi.h
index 1ad0ef9..3e81ef6 100644
--- a/core/hdd/inc/wlan_hdd_napi.h
+++ b/core/hdd/inc/wlan_hdd_napi.h
@@ -65,6 +65,7 @@
int hdd_napi_apply_throughput_policy(struct hdd_context_s *hddctx,
uint64_t tx_packets,
uint64_t rx_packets);
+int hdd_napi_serialize(int is_on);
#else /* FEATURE_NAPI and NOT HELIUM */
static inline int hdd_napi_apply_throughput_policy(struct hdd_context_s *hddctx,
uint64_t tx_packets,
@@ -72,6 +73,10 @@
{
return 0;
}
+static inline int hdd_napi_serialize(int is_on)
+{
+ return -EINVAL;
+};
#endif /* HELIUMPLUS */
#else /* ! defined(FEATURE_NAPI) */
diff --git a/core/hdd/src/wlan_hdd_napi.c b/core/hdd/src/wlan_hdd_napi.c
index 3a20bff..3e5766f 100644
--- a/core/hdd/src/wlan_hdd_napi.c
+++ b/core/hdd/src/wlan_hdd_napi.c
@@ -267,6 +267,7 @@
* Return: 0 : no action taken, or action return code
* !0: error, or action error code
*/
+static int napi_tput_policy_delay;
int hdd_napi_apply_throughput_policy(struct hdd_context_s *hddctx,
uint64_t tx_packets,
uint64_t rx_packets)
@@ -279,6 +280,19 @@
NAPI_DEBUG("-->%s(tx=%lld, rx=%lld)", __func__, tx_packets, rx_packets);
+ if (unlikely(napi_tput_policy_delay < 0))
+ napi_tput_policy_delay = 0;
+ if (napi_tput_policy_delay > 0) {
+ NAPI_DEBUG("%s: delaying policy; delay-count=%d",
+ __func__, napi_tput_policy_delay);
+ napi_tput_policy_delay--;
+
+ /* make sure the next timer call calls us */
+ hddctx->cur_vote_level = -1;
+
+ return rc;
+ }
+
if ((napid != NULL) &&
(enabled = hdd_napi_enabled(HDD_NAPI_ANY))) {
if (packets > hddctx->config->busBandwidthHighThreshold)
@@ -295,7 +309,47 @@
}
return rc;
}
-#endif
+
+/**
+ * hdd_napi_serialize() - serialize all NAPI activities
+ * @is_on: 1="serialize" or 0="de-serialize"
+ *
+ * Start/stop "serial-NAPI-mode".
+ * NAPI serial mode describes a state where all NAPI operations are forced to be
+ * run serially. This is achieved by ensuring all NAPI instances are run on the
+ * same CPU, so forced to be serial.
+ * NAPI life-cycle:
+ * - Interrupt is received for a given CE.
+ * - In the ISR, the interrupt is masked and corresponding NAPI instance
+ * is scheduled, to be run as a bottom-half.
+ * - Bottom-half starts with a poll call (by the net_rx softirq). There may be
+ * one of more subsequent calls until the work is complete.
+ * - Once the work is complete, the poll handler enables the interrupt and
+ * the cycle re-starts.
+ *
+ * Return: <0: error-code (operation failed)
+ * =0: success
+ * >0: status (not used)
+ */
+int hdd_napi_serialize(int is_on)
+{
+ int rc;
+ hdd_context_t *hdd_ctx;
+#define POLICY_DELAY_FACTOR (1)
+ rc = hif_napi_serialize(cds_get_context(QDF_MODULE_ID_HIF), is_on);
+ if ((rc == 0) && (is_on == 0)) {
+ /* apply throughput policy after one timeout */
+ napi_tput_policy_delay = POLICY_DELAY_FACTOR;
+
+ /* make sure that bus_bandwidth trigger is executed */
+ hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+ if (hdd_ctx != NULL)
+ hdd_ctx->cur_vote_level = -1;
+
+ }
+ return rc;
+}
+#endif /* HELIUMPLUS */
/**
* hdd_napi_poll() - NAPI poll function