qcacld-3.0: Avoid spin_lock_bh in ipa wlan rx callback

Spin_lock_bh is introduced in ipa wlan rx path by security fix
I0c0bc6e60efa193126ba1e3eca36c5e02f7f76a3,
wlan_ipa_w2i_cb->cdp_peer_state_get->dp_get_peer_state->
dp_peer_find_hash_find->qdf_spin_unlock_bh(&soc->peer_hash_lock),
which make rx pkt aggregation failed, for each rx pkt, once
put into backlog queue, net_rx soft irq is scheduled to handle it.
which make rx throughput failed to meet KPI.

TO avoid spin_lock_bh don't call cdp_peer_state_get for each rx pkt,
only call 1 time, and save peer auth state in IPA context, for following
pkts, just get peer auth state from IPA context without spin_lock_bh.

Change-Id: I36196bab4626194bda254219c4c44dc4f029cff0
CRs-Fixed: 3076978
This commit is contained in:
Jianmin Zhu
2021-10-14 21:23:35 +08:00
committed by Madan Koyyalamudi
부모 4865b44352
커밋 62562f2527
2개의 변경된 파일105개의 추가작업 그리고 5개의 파일을 삭제

파일 보기

@@ -330,7 +330,8 @@ struct wlan_ipa_priv;
* @interface_lock: Interface lock
* @ifa_address: Interface address
* @stats: Interface stats
* @bssid: BSSID. valid only for sta iface ctx;
* @bssid: BSSID. valid only for sta iface ctx
* @is_authenticated: is peer authenticated
*/
struct wlan_ipa_iface_context {
struct wlan_ipa_priv *ipa_ctx;
@@ -349,6 +350,7 @@ struct wlan_ipa_iface_context {
uint32_t ifa_address;
struct wlan_ipa_iface_stats stats;
struct qdf_mac_addr bssid;
uint8_t is_authenticated;
};
/**
@@ -397,11 +399,13 @@ struct wlan_ipa_stats {
/**
* struct ipa_uc_stas_map - IPA UC assoc station map
* @is_reserved: STA reserved flag
* @is_authenticated: is peer authenticated
* @mac_addr: Station mac address
*/
struct ipa_uc_stas_map {
bool is_reserved;
struct qdf_mac_addr mac_addr;
uint8_t is_authenticated;
};
/**

파일 보기

@@ -1009,6 +1009,100 @@ wlan_ipa_eapol_intrabss_fwd_check(struct wlan_ipa_priv *ipa_ctx,
return true;
}
#ifdef MDM_PLATFORM
static void
wlan_ipa_set_sap_client_auth(struct wlan_ipa_priv *ipa_ctx, uint8_t *peer_mac,
uint8_t is_authenticated)
{
uint8_t idx;
struct ipa_uc_stas_map *sta_map;
for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
sta_map = &ipa_ctx->assoc_stas_map[idx];
if (sta_map->is_reserved &&
qdf_is_macaddr_equal(&sta_map->mac_addr,
(struct qdf_mac_addr *)peer_mac)) {
sta_map->is_authenticated = is_authenticated;
break;
}
}
}
static inline uint8_t
wlan_ipa_get_sap_client_auth(struct wlan_ipa_priv *ipa_ctx, uint8_t *peer_mac)
{
uint8_t idx;
struct ipa_uc_stas_map *sta_map;
for (idx = 0; idx < WLAN_IPA_MAX_STA_COUNT; idx++) {
sta_map = &ipa_ctx->assoc_stas_map[idx];
if (sta_map->is_reserved &&
qdf_is_macaddr_equal(&sta_map->mac_addr,
(struct qdf_mac_addr *)peer_mac)) {
return sta_map->is_authenticated;
}
}
return false;
}
static inline uint8_t
wlan_ipa_is_peer_authenticated(ol_txrx_soc_handle dp_soc,
struct wlan_ipa_iface_context *iface,
uint8_t *peer_mac)
{
uint8_t is_authenticated = false;
if (iface->device_mode == QDF_SAP_MODE) {
is_authenticated = wlan_ipa_get_sap_client_auth(iface->ipa_ctx,
peer_mac);
if (is_authenticated)
return is_authenticated;
is_authenticated = cdp_peer_state_get(dp_soc,
iface->session_id,
peer_mac);
if (is_authenticated == OL_TXRX_PEER_STATE_AUTH)
wlan_ipa_set_sap_client_auth(iface->ipa_ctx,
peer_mac,
true);
else
is_authenticated = false;
} else if (iface->device_mode == QDF_STA_MODE) {
is_authenticated = iface->is_authenticated;
if (is_authenticated)
return is_authenticated;
is_authenticated = cdp_peer_state_get(dp_soc,
iface->session_id,
peer_mac);
if (is_authenticated == OL_TXRX_PEER_STATE_AUTH)
iface->is_authenticated = true;
else
is_authenticated = false;
}
return is_authenticated;
}
#else
static void
wlan_ipa_set_sap_client_auth(struct wlan_ipa_priv *ipa_ctx, uint8_t *peer_mac,
uint8_t is_authenticated)
{}
static inline bool
wlan_ipa_is_peer_authenticated(ol_txrx_soc_handle dp_soc,
struct wlan_ipa_iface_context *iface,
uint8_t *peer_mac)
{
uint8_t is_authenticated = 0;
is_authenticated = cdp_peer_state_get(dp_soc,
iface->session_id,
peer_mac);
return (is_authenticated == OL_TXRX_PEER_STATE_AUTH);
}
#endif
/**
* __wlan_ipa_w2i_cb() - WLAN to IPA callback handler
* @priv: pointer to private data registered with IPA (we register a
@@ -1106,10 +1200,10 @@ static void __wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt,
* non-EAPOL/WAPI frames to be intrabss forwarded
* or submitted to stack.
*/
if (cdp_peer_state_get(ipa_ctx->dp_soc,
iface_context->session_id,
&peer_mac_addr.bytes[0]) !=
OL_TXRX_PEER_STATE_AUTH && !is_eapol_wapi) {
if (!wlan_ipa_is_peer_authenticated(ipa_ctx->dp_soc,
iface_context,
&peer_mac_addr.bytes[0]) &&
!is_eapol_wapi) {
ipa_err_rl("Non EAPOL/WAPI packet received when peer " QDF_MAC_ADDR_FMT " is unauthorized",
QDF_MAC_ADDR_REF(peer_mac_addr.bytes));
ipa_ctx->ipa_rx_internal_drop_count++;
@@ -1585,6 +1679,7 @@ static void wlan_ipa_cleanup_iface(struct wlan_ipa_iface_context *iface_context,
QDF_BUG(0);
}
iface_context->is_authenticated = false;
iface_context->dev = NULL;
iface_context->device_mode = QDF_MAX_NO_OF_MODE;
iface_context->session_id = WLAN_IPA_MAX_SESSION;
@@ -2836,6 +2931,7 @@ static QDF_STATUS __wlan_ipa_wlan_evt(qdf_netdev_t net_dev, uint8_t device_mode,
}
qdf_mutex_acquire(&ipa_ctx->event_lock);
wlan_ipa_set_sap_client_auth(ipa_ctx, mac_addr, false);
if (!ipa_ctx->sap_num_connected_sta) {
qdf_mutex_release(&ipa_ctx->event_lock);
ipa_debug("%s: Evt: %d, Client already disconnected",