From ab8cea0b3a3661f021f9a5a72ce0cb285bc16eb6 Mon Sep 17 00:00:00 2001 From: jiad Date: Thu, 24 May 2018 09:16:14 +0800 Subject: [PATCH] qcacld-3.0: Fix SKB free for WLAN IPA exceptions There are two types of WLAN IPA exceptions, where WLAN driver is involved for packet processing. One is for RX exceptions, such as ICMP or Intra-BSS packets. The other one is for WDI 1.0 MCC TX SW path, where packet queueing is happening in WLAN driver. In both cases, skb is allocated in IPA driver. If NBUF_MEMORY_DEBUG is defined and qdf_net_buf_debug_acquire_skb() is not invoked for the skb, qdf_nbuf_free() will trigger ASSERT to report unallocated buffer. For early processing of RX exceptions, dev_kfree_skb_any() needs to be called instead of qdf_nbuf_free() otherwise above ASSERT will be triggered. For MCC TX SW path, ipa_free_skb() should be called to free skb to IPA driver. Change-Id: I039cb20673ce3aa98056529f7609801f76c4c16a CRs-Fixed: 2247339 --- components/ipa/core/src/wlan_ipa_core.c | 48 +++++++++++++++++++------ 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 4f49adfd460b..345f14da1840 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -428,8 +428,19 @@ static void wlan_ipa_pm_flush(void *data) pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; dequeued++; - wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, - pm_tx_cb->ipa_tx_desc); + if (pm_tx_cb->exception) { + if (ipa_ctx->softap_xmit && + pm_tx_cb->iface_context->dev) { + ipa_ctx->softap_xmit(skb, + pm_tx_cb->iface_context->dev); + ipa_ctx->stats.num_tx_fwd_ok++; + } else { + dev_kfree_skb_any(skb); + } + } else { + wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, + pm_tx_cb->ipa_tx_desc); + } qdf_spin_lock_bh(&ipa_ctx->pm_lock); } @@ -549,8 +560,19 @@ static void wlan_ipa_pm_flush(void *data) pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; dequeued++; - wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, - pm_tx_cb->ipa_tx_desc); + if (pm_tx_cb->exception) { + if (ipa_ctx->softap_xmit && + pm_tx_cb->iface_context->dev) { + ipa_ctx->softap_xmit(skb, + pm_tx_cb->iface_context->dev); + ipa_ctx->stats.num_tx_fwd_ok++; + } else { + dev_kfree_skb_any(skb); + } + } else { + wlan_ipa_send_pkt_to_tl(pm_tx_cb->iface_context, + pm_tx_cb->ipa_tx_desc); + } qdf_spin_lock_bh(&ipa_ctx->pm_lock); } @@ -658,8 +680,7 @@ static void wlan_ipa_forward(struct wlan_ipa_priv *ipa_ctx, ipa_ctx->stats.num_tx_fwd_ok++; } } else { - pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; - ipa_free_skb(pm_tx_cb->ipa_tx_desc); + dev_kfree_skb_any(skb); } } } @@ -695,7 +716,7 @@ static enum wlan_ipa_forward_type wlan_ipa_intrabss_forward( iface_ctx->session_id))) { /* Drop the packet*/ ipa_ctx->stats.num_tx_fwd_err++; - kfree_skb(skb); + dev_kfree_skb_any(skb); ret = WLAN_IPA_FORWARD_PKT_DISCARD; return ret; } @@ -764,7 +785,7 @@ static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, ipa_err("IPA_RECEIVE: Invalid iface_id: %u", iface_id); ipa_ctx->ipa_rx_internal_drop_count++; - qdf_nbuf_free(skb); + dev_kfree_skb_any(skb); return; } @@ -772,7 +793,7 @@ static void wlan_ipa_w2i_cb(void *priv, qdf_ipa_dp_evt_type_t evt, if (!iface_context->tl_context) { ipa_err("IPA_RECEIVE: TL context is NULL"); ipa_ctx->ipa_rx_internal_drop_count++; - qdf_nbuf_free(skb); + dev_kfree_skb_any(skb); return; } @@ -2324,8 +2345,13 @@ void wlan_ipa_flush(struct wlan_ipa_priv *ipa_ctx) qdf_spin_unlock_bh(&ipa_ctx->pm_lock); pm_tx_cb = (struct wlan_ipa_pm_tx_cb *)skb->cb; - if (pm_tx_cb->ipa_tx_desc) - ipa_free_skb(pm_tx_cb->ipa_tx_desc); + + if (pm_tx_cb->exception) { + dev_kfree_skb_any(skb); + } else { + if (pm_tx_cb->ipa_tx_desc) + ipa_free_skb(pm_tx_cb->ipa_tx_desc); + } qdf_spin_lock_bh(&ipa_ctx->pm_lock); }