Jelajahi Sumber

qcacld-3.0: Optimize TX path in function __hdd_hard_start_xmit()

Currently hdd_cm_is_vdev_associated() and cdp_peer_state_get() per
packet check consumed much CPU on TX path, they will hold spin
lock which will introduce contention between different TX streams.

solution:
(1) check is_authenticated in sta_ctx->conn_info, if true,
then connection has been established already.
(2) clear is_authenticated flag if disconnection happened for
STA and P2P client.

Change-Id: I208608eba7bab69c8795e25495424327b7f2331f
CRs-Fixed: 3165165
Jinwei Chen 3 tahun lalu
induk
melakukan
075572020c

+ 16 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -1592,6 +1592,22 @@ struct hdd_adapter {
 				(&(adapter)->session.ap.hostapd_state)
 #define WLAN_HDD_GET_SAP_CTX_PTR(adapter) ((adapter)->session.ap.sap_context)
 
+/**
+ * hdd_is_sta_authenticated() - check if given adapter's STA
+ *				session authenticated
+ * @adapter: adapter pointer
+ *
+ * Return: STA session is_authenticated flag value
+ */
+static inline
+uint8_t hdd_is_sta_authenticated(struct hdd_adapter *adapter)
+{
+	struct hdd_station_ctx *sta_ctx =
+			WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+	return sta_ctx->conn_info.is_authenticated;
+}
+
 #ifdef WLAN_FEATURE_NAN
 #define WLAN_HDD_IS_NDP_ENABLED(hdd_ctx) ((hdd_ctx)->nan_datapath_enabled)
 #else

+ 5 - 0
core/hdd/src/wlan_hdd_cm_disconnect.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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 above
@@ -225,6 +226,7 @@ QDF_STATUS wlan_hdd_cm_issue_disconnect(struct hdd_adapter *adapter,
 		return QDF_STATUS_E_INVAL;
 	hdd_place_marker(adapter, "TRY TO DISCONNECT", NULL);
 	reset_mscs_params(adapter);
+	hdd_conn_set_authenticated(adapter, false);
 	wlan_hdd_netif_queue_control(adapter,
 				     WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
 				     WLAN_CONTROL_PATH);
@@ -318,6 +320,8 @@ hdd_cm_disconnect_complete_pre_user_update(struct wlan_objmgr_vdev *vdev,
 		hdd_err("adapter is NULL for vdev %d", wlan_vdev_get_id(vdev));
 		return QDF_STATUS_E_INVAL;
 	}
+
+	hdd_conn_set_authenticated(adapter, false);
 	hdd_napi_serialize(0);
 	hdd_disable_and_flush_mc_addr_list(adapter, pmo_peer_disconnect);
 	__hdd_cm_disconnect_handler_pre_user_update(adapter);
@@ -433,6 +437,7 @@ hdd_cm_disconnect_complete_post_user_update(struct wlan_objmgr_vdev *vdev,
 		hdd_err("adapter is NULL for vdev %d", wlan_vdev_get_id(vdev));
 		return QDF_STATUS_E_INVAL;
 	}
+
 	if (adapter->device_mode == QDF_STA_MODE) {
 	/* Inform FTM TIME SYNC about the disconnection with the AP */
 		hdd_ftm_time_sync_sta_state_notify(

+ 18 - 7
core/hdd/src/wlan_hdd_tx_rx.c

@@ -663,8 +663,8 @@ void hdd_reset_all_adapters_connectivity_stats(struct hdd_context *hdd_ctx)
 
 /**
  * hdd_is_tx_allowed() - check if Tx is allowed based on current peer state
+ * @adapter: pointer to adapter structure
  * @skb: pointer to OS packet (sk_buff)
- * @vdev_id: virtual interface id
  * @peer_mac: Peer mac address
  *
  * This function gets the peer state from DP and check if it is either
@@ -674,7 +674,8 @@ void hdd_reset_all_adapters_connectivity_stats(struct hdd_context *hdd_ctx)
  *
  * Return: true if Tx is allowed and false otherwise.
  */
-static inline bool hdd_is_tx_allowed(struct sk_buff *skb, uint8_t vdev_id,
+static inline bool hdd_is_tx_allowed(struct hdd_adapter *adapter,
+				     struct sk_buff *skb,
 				     uint8_t *peer_mac)
 {
 	enum ol_txrx_peer_state peer_state;
@@ -682,7 +683,16 @@ static inline bool hdd_is_tx_allowed(struct sk_buff *skb, uint8_t vdev_id,
 
 	QDF_BUG(soc);
 
-	peer_state = cdp_peer_state_get(soc, vdev_id, peer_mac);
+	/**
+	 * If is_authenticated is true, then peer state is
+	 * OL_TXRX_PEER_STATE_AUTH already, skip cdp peer
+	 * API which is not efficient for T-put.
+	 */
+	if (adapter->device_mode != QDF_NDI_MODE &&
+	    hdd_is_sta_authenticated(adapter))
+		return true;
+
+	peer_state = cdp_peer_state_get(soc, adapter->vdev_id, peer_mac);
 	if (likely(OL_TXRX_PEER_STATE_AUTH == peer_state))
 		return true;
 	if (OL_TXRX_PEER_STATE_CONN == peer_state &&
@@ -1007,7 +1017,9 @@ void hdd_get_transmit_mac_addr(struct hdd_adapter *adapter, struct sk_buff *skb,
 			qdf_copy_macaddr(mac_addr_tx_allowed,
 					 (struct qdf_mac_addr *)skb->data);
 	} else {
-		if (hdd_cm_is_vdev_associated(adapter))
+		/* If is_authenticated is true, vdev must be associated */
+		if (qdf_likely(hdd_is_sta_authenticated(adapter)) ||
+		    hdd_cm_is_vdev_associated(adapter))
 			qdf_copy_macaddr(mac_addr_tx_allowed,
 					 &sta_ctx->conn_info.bssid);
 	}
@@ -1130,7 +1142,6 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb,
 	enum sme_qos_wmmuptype up;
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	bool granted;
-	struct hdd_station_ctx *sta_ctx = &adapter->session.station;
 	struct qdf_mac_addr mac_addr_tx_allowed = QDF_MAC_ADDR_ZERO_INIT;
 	uint8_t pkt_type = 0;
 	bool is_arp = false;
@@ -1270,7 +1281,7 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb,
 	if (((adapter->psb_changed & (1 << ac)) &&
 		likely(adapter->hdd_wmm_status.ac_status[ac].
 			is_access_allowed)) ||
-		((sta_ctx->conn_info.is_authenticated == false) &&
+		(!hdd_is_sta_authenticated(adapter) &&
 		 (QDF_NBUF_CB_PACKET_TYPE_EAPOL ==
 			QDF_NBUF_CB_GET_PACKET_TYPE(skb) ||
 		  QDF_NBUF_CB_PACKET_TYPE_WAPI ==
@@ -1337,7 +1348,7 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb,
 			sizeof(qdf_nbuf_data(skb)),
 			QDF_TX));
 
-	if (!hdd_is_tx_allowed(skb, adapter->vdev_id,
+	if (!hdd_is_tx_allowed(adapter, skb,
 			       mac_addr_tx_allowed.bytes)) {
 		QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
 			  QDF_TRACE_LEVEL_INFO_HIGH,