diff options
| author | Prashanth Bhatta <bhattap@qca.qualcomm.com> | 2014-06-03 09:54:05 -0700 |
|---|---|---|
| committer | Pitani Venkata Rajesh Kumar <c_vpitan@qti.qualcomm.com> | 2014-06-07 00:56:36 +0530 |
| commit | dd5cec7983f23e336bef9828ec0e5124822bc8e2 (patch) | |
| tree | 0bc9a6ba94e3dfdaa97b4293fbf7dee039a98224 | |
| parent | 81c9f2a3c6f811de4db2a2d923dfd444c340c60a (diff) | |
qcacld: ipa: Fix spinlock lock-up issue
On IPA TX and RX path, spin lock is used but IPA call backs are
called in soft irq context and leading to lock-up. This spin lock
protection is added to prevent accessing IPA data structure when
interface is disconnected. But this protection is only required
on TX path and RX path IPA shouldn't receive any packets as
disconnect happened from lower layer itself. Fixing this issue by
using spin_lock_bh and removing the usage of spin lock on RX
path.
Change-Id: I7f3bd21192296328ad9f94eafc9139b82dc7ba09
CRs-fixed: 667732
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_ipa.c | 35 |
1 files changed, 13 insertions, 22 deletions
diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c index 35e2548ab404..6241785f2733 100644 --- a/CORE/HDD/src/wlan_hdd_ipa.c +++ b/CORE/HDD/src/wlan_hdd_ipa.c @@ -158,7 +158,7 @@ struct hdd_ipa_iface_context { uint8_t iface_id; /* This iface ID */ uint8_t sta_id; /* This iface station ID */ - vos_spin_lock_t interface_lock; + adf_os_spinlock_t interface_lock; uint32_t ifa_address; }; @@ -722,8 +722,8 @@ static void hdd_ipa_process_evt(int evt, void *priv) rxt = priv; adapter = hdd_ipa->hdd_ctx->sta_to_adapter[rxt->sta_id]; - if (!adapter || - (adapter && adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) { + if (!adapter || !adapter->ipa_context || + adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid sta_id"); buf = rxt->rx_buf_list; while (buf) { @@ -739,12 +739,6 @@ static void hdd_ipa_process_evt(int evt, void *priv) iface_context = (struct hdd_ipa_iface_context *) adapter->ipa_context; - if (iface_context) { - vos_spin_lock_acquire(&iface_context->interface_lock); - } - else { - return; - } /* send_desc_head is a anchor node */ send_desc_head = hdd_ipa_get_desc_from_freeq(); @@ -767,7 +761,6 @@ static void hdd_ipa_process_evt(int evt, void *priv) #ifdef HDD_IPA_EXTRA_DP_COUNTERS hdd_ipa->stats.rxt_dh_drop++; #endif - vos_spin_lock_release(&iface_context->interface_lock); return; } @@ -818,7 +811,6 @@ static void hdd_ipa_process_evt(int evt, void *priv) #endif buf = next_buf; } - vos_spin_lock_release(&iface_context->interface_lock); #ifdef HDD_IPA_EXTRA_DP_COUNTERS if (cur_cnt == 0) @@ -1105,21 +1097,20 @@ static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, hdd_ipa->stats.tx_ipa_recv++; - vos_spin_lock_acquire(&iface_context->interface_lock); - if (iface_context->adapter) { - interface_id = iface_context->adapter->sessionId; - } - else{ + adf_os_spin_lock_bh(&iface_context->interface_lock); + if (!iface_context->adapter) { HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN, "Interface Down"); ipa_free_skb(ipa_tx_desc); - vos_spin_lock_release(&iface_context->interface_lock); + adf_os_spin_unlock_bh(&iface_context->interface_lock); return; } - vos_spin_lock_release(&iface_context->interface_lock); + interface_id = iface_context->adapter->sessionId; ++iface_context->adapter->stats.tx_packets; iface_context->adapter->stats.tx_bytes += ipa_tx_desc->skb->len; + adf_os_spin_unlock_bh(&iface_context->interface_lock); + skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, iface_context->tl_context, ipa_tx_desc->skb, interface_id); if (skb) { @@ -1485,11 +1476,11 @@ static void hdd_ipa_cleanup_iface(struct hdd_ipa_iface_context *iface_context) hdd_ipa_clean_hdr(iface_context->adapter); - vos_spin_lock_acquire(&iface_context->interface_lock); + adf_os_spin_lock_bh(&iface_context->interface_lock); iface_context->adapter->ipa_context = NULL; iface_context->adapter = NULL; iface_context->tl_context = NULL; - vos_spin_lock_release(&iface_context->interface_lock); + adf_os_spin_unlock_bh(&iface_context->interface_lock); iface_context->ifa_address = 0; } @@ -1941,7 +1932,7 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) iface_context->prod_client = hdd_ipa_adapter_2_client[i].prod_client; iface_context->iface_id = i; - vos_spin_lock_init(&iface_context->interface_lock); + adf_os_spinlock_init(&iface_context->interface_lock); } ret = hdd_ipa_setup_rm(hdd_ipa); @@ -1989,7 +1980,7 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx) /* destory the interface lock */ for (i = 0; i < HDD_IPA_MAX_IFACE; i++) { iface_context = &hdd_ipa->iface_context[i]; - vos_spin_lock_destroy(&iface_context->interface_lock); + adf_os_spinlock_destroy(&iface_context->interface_lock); } hdd_ipa_debugfs_remove(hdd_ipa); |
