From 83b8ffc556e92304b754d22df65ac5f5fcdb1910 Mon Sep 17 00:00:00 2001 From: Vivek Date: Tue, 18 Sep 2018 16:58:38 +0530 Subject: [PATCH] qcacmn: Protect queue access inside activate_multiple_cmds API The removal of blocking command from active non scan queue, can result in movement of either single/multiple blocking/non blocking commands from pending to active queue, so the activation of new command(s) moved to active queue as a result removal of blocking command, is done inside the wlan_serialization_activate_multiple_cmd where the active list is traversed and activated, which needs to be protected by the queue lock to avoid concurrent access and updates to the cmds in the queue from different contexts. Change-Id: Ibf3034083d348ef7187bfac9cf2c540c748cd678 CRs-Fixed: 2317626 --- .../src/wlan_serialization_internal.c | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/umac/cmn_services/serialization/src/wlan_serialization_internal.c b/umac/cmn_services/serialization/src/wlan_serialization_internal.c index 2285f5f35168..6901fa74db1c 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_internal.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_internal.c @@ -243,9 +243,12 @@ wlan_serialization_activate_multiple_cmd( struct wlan_objmgr_psoc *psoc = NULL; pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; - active_queue = &pdev_queue->active_list; + wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); + + active_queue = &pdev_queue->active_list; qsize = wlan_serialization_list_size(active_queue); + while (qsize--) { peek_status = wlan_serialization_get_cmd_from_queue( active_queue, &nnode); @@ -264,6 +267,18 @@ wlan_serialization_activate_multiple_cmd( continue; } + qdf_atomic_clear_bit(CMD_MARKED_FOR_ACTIVATION, + &active_cmd_list->cmd_in_use); + + qdf_atomic_set_bit(CMD_IS_ACTIVE, + &active_cmd_list->cmd_in_use); + + vdev_id = wlan_vdev_get_id(active_cmd_list->cmd.vdev); + pdev_queue->vdev_active_cmd_bitmap |= (1 << vdev_id); + + if (active_cmd_list->cmd.is_blocking) + pdev_queue->blocking_cmd_active = 1; + /* * Command is already pushed to active queue. * Now start the timer. @@ -277,25 +292,19 @@ wlan_serialization_activate_multiple_cmd( active_cmd_list->cmd.cmd_id, "WLAN_SER_CB_ACTIVATE_CMD"); + wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); + status = active_cmd_list->cmd.cmd_cb(&active_cmd_list->cmd, WLAN_SER_CB_ACTIVATE_CMD); - qdf_atomic_clear_bit(CMD_MARKED_FOR_ACTIVATION, - &active_cmd_list->cmd_in_use); - - qdf_atomic_set_bit(CMD_IS_ACTIVE, - &active_cmd_list->cmd_in_use); - - vdev_id = wlan_vdev_get_id(active_cmd_list->cmd.vdev); - pdev_queue->vdev_active_cmd_bitmap |= (1 << vdev_id); - - if (active_cmd_list->cmd.is_blocking) - pdev_queue->blocking_cmd_active = 1; - if (QDF_IS_STATUS_ERROR(status)) wlan_serialization_dequeue_cmd(&active_cmd_list->cmd, true); + + wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); } + + wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); return status; }