From 7c1fe52d515d94af8baba5213d2d7a86fdc20293 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 20 Feb 2019 12:21:26 +0530 Subject: [PATCH] qcacmn: Get vdev_id before releasing ref while flushing active cmd In wlan_ser_cancel_non_scan_cmd, cmd.vdev pointer is used to get vdev id after WLAN_SER_CB_RELEASE_MEM_CMD is called. In WLAN_SER_CB_RELEASE_MEM_CMD the command release the vdev ref count and it may lead to physical deletion of vdev. Thus getting vdev id from vdev may result in invalid vdev_id and thus proper bits are not reset in vdev_active_cmd_bitmap for the vdev. Thus no new blocking command will be allowed in serialization active queue. Fix is to get proper vdev_id before WLAN_SER_CB_RELEASE_MEM_CMD is called and use that to reset the pdev_q->vdev_active_cmd_bitmap bit for vdev_id Change-Id: I2756f1632a72f086e9d214a437ad794ae08afc45 CRs-Fixed: 2395851 --- .../src/wlan_serialization_non_scan.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c b/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c index ceb6e93bf1aa..e1a1f9a4d683 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c @@ -467,6 +467,8 @@ wlan_ser_cancel_non_scan_cmd( qdf_list_t *vdev_queue; struct wlan_serialization_pdev_queue *pdev_q; uint32_t qsize; + uint8_t vdev_id; + bool is_blocking; struct wlan_serialization_command_list *cmd_list = NULL; struct wlan_serialization_command cmd_bkup; qdf_list_node_t *nnode = NULL, *pnode = NULL; @@ -618,6 +620,9 @@ wlan_ser_cancel_non_scan_cmd( } nnode = pnode; + vdev_id = wlan_vdev_get_id(cmd_bkup.vdev); + is_blocking = cmd_bkup.is_blocking; + wlan_ser_update_cmd_history(pdev_q, &cmd_bkup, SER_CANCEL, false, is_active_queue); @@ -643,12 +648,14 @@ wlan_ser_cancel_non_scan_cmd( wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock); if (is_active_queue) { - if (cmd_bkup.is_blocking) + if (is_blocking) pdev_q->blocking_cmd_active = 0; - pdev_q->vdev_active_cmd_bitmap &= - ~(1 << wlan_vdev_get_id(cmd_bkup.vdev)); + pdev_q->vdev_active_cmd_bitmap &= ~(1 << vdev_id); + ser_debug("pdev_q->vdev_active_cmd_bitmap %x after reseting for vdev %d", + pdev_q->vdev_active_cmd_bitmap, + vdev_id); } else { - if (cmd_bkup.is_blocking) + if (is_blocking) pdev_q->blocking_cmd_waiting--; status = WLAN_SER_CMD_IN_PENDING_LIST;