wlan: Fix the race condition in RX Low resource recovery mechanism
Set the wpalPacketAvailableCB before we try to get a VOS
packet from the 'free list' and reset it if vos_pkt_get_packet()
returns a valid packet. This order is required to avoid the
following race condition:
1. The call to vos_pkt_get_packet() from wpalPacketAlloc() in
RX_Thread determines that no more packets are available in
the 'free list' and sets the low resource callbacks.
2. In parallel vos_pkt_return_packet() is called in MC_Thread for a
Management frame before wpalPacketAlloc() gets a chance to set
wpalPacketAvailableCB and since the 'low resource callbacks'
are set the, callback function - wpalPacketRXLowResourceCB is
executed.But as wpalPacketAvailableCB is still NULL the low
resource recovery fails.
Change-Id: Ie1cea3c9411e314a4309efdc207f4f69953f844f
CRs-Fixed: 591906
diff --git a/CORE/WDI/WPAL/src/wlan_qct_pal_packet.c b/CORE/WDI/WPAL/src/wlan_qct_pal_packet.c
index d8b3eb9..5eb8adf 100644
--- a/CORE/WDI/WPAL/src/wlan_qct_pal_packet.c
+++ b/CORE/WDI/WPAL/src/wlan_qct_pal_packet.c
@@ -176,6 +176,22 @@
break;
case eWLAN_PAL_PKT_TYPE_RX_RAW:
+ /* Set the wpalPacketAvailableCB before we try to get a VOS
+ * packet from the 'free list' and reset it if vos_pkt_get_packet()
+ * returns a valid packet. This order is required to avoid the
+ * race condition:
+ * 1. The below call to vos_pkt_get_packet() in RX_Thread determines
+ * that no more packets are available in the 'free list' and sets
+ * the low resource callbacks.
+ * 2. in parallel vos_pkt_return_packet() is called in MC_Thread for a
+ * Management frame before wpalPacketAlloc() gets a chance to set
+ * wpalPacketAvailableCB and since the 'low resource callbacks'
+ * are set the callback function - wpalPacketRXLowResourceCB is
+ * executed,but since wpalPacketAvailableCB is still NULL the low
+ * resource recovery fails.
+ */
+ wpalPacketAvailableCB = rxLowCB;
+
vosStatus = vos_pkt_get_packet(&pVosPkt, VOS_PKT_TYPE_RX_RAW,
nPktSize, 1, VOS_FALSE,
wpalPacketRXLowResourceCB, usrData);
@@ -184,12 +200,9 @@
/* Reserve the entire raw rx buffer for DXE */
if( vosStatus == VOS_STATUS_SUCCESS )
{
+ wpalPacketAvailableCB = NULL;
vosStatus = vos_pkt_reserve_head_fast( pVosPkt, &pData, nPktSize );
}
- else
- {
- wpalPacketAvailableCB = rxLowCB;
- }
#endif /* FEATURE_R33D */
if((NULL != pVosPkt) && (VOS_STATUS_E_RESOURCES != vosStatus))
{