From 883e4c1d79f8217c0534d525e89f21dbcc31143a Mon Sep 17 00:00:00 2001 From: Vivek Date: Sun, 9 Dec 2018 16:00:38 +0530 Subject: [PATCH] qcacmn: Additional checks for moving command to active queue The current implementation was not checking for pending queue status before adding command to pending queue. This was causing an issue, when, after removal of an active command, we were preepmted and a new request came, it made it to the active queue. Now when the previous thread resumed, and we attempted to move pending to active, it failed. Added the following new checks: 1. When adding command to active queue, make sure there is no commands in the pending queue 2. When moving from pending to active, make sure it is allowed to add commands to the active queue. Change-Id: Ief16c22f6f7e2cdc105e24f164e5891bfe806662 CRs-Fixed: 2356719 --- .../src/wlan_serialization_internal.c | 6 ++- .../src/wlan_serialization_non_scan.c | 41 ++++++++++++++++--- .../src/wlan_serialization_non_scan_i.h | 13 ++++++ .../src/wlan_serialization_scan.c | 25 +++++++++++ .../src/wlan_serialization_scan_i.h | 13 ++++++ 5 files changed, 91 insertions(+), 7 deletions(-) diff --git a/umac/cmn_services/serialization/src/wlan_serialization_internal.c b/umac/cmn_services/serialization/src/wlan_serialization_internal.c index 6b4f7615c77e..6c30a94cc6fd 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_internal.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_internal.c @@ -318,10 +318,12 @@ wlan_serialization_is_active_cmd_allowed(struct wlan_serialization_command *cmd) if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN) active_cmd_allowed = - wlan_serialization_is_active_scan_cmd_allowed(cmd); + (wlan_serialization_is_active_scan_cmd_allowed(cmd) && + wlan_serialization_is_scan_pending_queue_empty(cmd)); else active_cmd_allowed = - wlan_serialization_is_active_non_scan_cmd_allowed(cmd); + (wlan_serialization_is_active_non_scan_cmd_allowed(cmd) && + wlan_serialization_is_non_scan_pending_queue_empty(cmd)); ser_debug("active cmd_type[%d] cmd_id[%d] allowed: %d", cmd->cmd_type, 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 d22ebb20cf99..95ef1ddc9564 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_non_scan.c @@ -28,6 +28,32 @@ #include "wlan_serialization_utils_i.h" #include "wlan_serialization_non_scan_i.h" +bool +wlan_serialization_is_non_scan_pending_queue_empty( + struct wlan_serialization_command *cmd) +{ + struct wlan_objmgr_vdev *vdev = NULL; + struct wlan_ser_vdev_obj *ser_vdev_obj = NULL; + struct wlan_serialization_vdev_queue *vdev_q; + bool status = false; + + vdev = wlan_serialization_get_vdev_from_cmd(cmd); + + if (!vdev) { + ser_err("vdev object is invalid"); + goto error; + } + + ser_vdev_obj = wlan_serialization_get_vdev_obj(vdev); + vdev_q = &ser_vdev_obj->vdev_q[SER_VDEV_QUEUE_COMP_NON_SCAN]; + + if (qdf_list_empty(&vdev_q->pending_list)) + status = true; + +error: + return status; +} + /** * wlan_serialization_is_active_nonscan_cmd_allowed() - find if cmd allowed * @pdev: pointer to pdev object @@ -36,6 +62,7 @@ * * Return: true or false */ + bool wlan_serialization_is_active_non_scan_cmd_allowed( struct wlan_serialization_command *cmd) @@ -267,18 +294,21 @@ wlan_ser_move_non_scan_pending_to_active( goto error; } + vdev_id = wlan_vdev_get_id(pending_cmd_list->cmd.vdev); + vdev_cmd_active = + pdev_queue->vdev_active_cmd_bitmap & + (1 << vdev_id); + if (!vdev_queue_lookup) { if (pending_cmd_list->cmd.is_blocking && pdev_queue->vdev_active_cmd_bitmap) { break; } - - vdev_id = wlan_vdev_get_id(pending_cmd_list->cmd.vdev); - vdev_cmd_active = - pdev_queue->vdev_active_cmd_bitmap & - (1 << vdev_id); if (vdev_cmd_active) continue; + } else { + if (vdev_cmd_active) + break; } qdf_mem_copy(&cmd_to_remove, &pending_cmd_list->cmd, @@ -320,6 +350,7 @@ wlan_ser_move_non_scan_pending_to_active( &pdev_queue->cmd_pool_list, &active_cmd_list->pdev_node); status = WLAN_SER_CMD_DENIED_UNSPECIFIED; + QDF_ASSERT(0); goto error; } diff --git a/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h b/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h index 065a5beba235..5426ae4c5ee1 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h +++ b/umac/cmn_services/serialization/src/wlan_serialization_non_scan_i.h @@ -35,6 +35,19 @@ #include "wlan_serialization_internal_i.h" #include "wlan_serialization_queue_i.h" +/** + * wlan_serialization_is_non_scan_pending_queue_empty() + * + * @cmd: Serialization command information + * + * This API will be find out if non scan cmd pending queue is empty. + * + * Return: true or false + */ +bool +wlan_serialization_is_non_scan_pending_queue_empty( + struct wlan_serialization_command *cmd); + /** * wlan_serialization_is_active_nonscan_cmd_allowed() - find if cmd allowed * to be enqueued in active queue diff --git a/umac/cmn_services/serialization/src/wlan_serialization_scan.c b/umac/cmn_services/serialization/src/wlan_serialization_scan.c index 54fbd5fb9d4d..d2917e844498 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_scan.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_scan.c @@ -52,6 +52,26 @@ wlan_serialization_active_scan_cmd_count_handler(struct wlan_objmgr_psoc *psoc, *count += wlan_serialization_list_size(&pdev_q->active_list); } +bool +wlan_serialization_is_scan_pending_queue_empty( + struct wlan_serialization_command *cmd) +{ + struct wlan_objmgr_pdev *pdev; + struct wlan_ser_pdev_obj *ser_pdev_obj = NULL; + struct wlan_serialization_pdev_queue *pdev_q; + bool status = false; + + pdev = wlan_serialization_get_pdev_from_cmd(cmd); + ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); + + pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; + + if (qdf_list_empty(&pdev_q->pending_list)) + status = true; + + return status; +} + bool wlan_serialization_is_active_scan_cmd_allowed( struct wlan_serialization_command *cmd) @@ -372,6 +392,11 @@ enum wlan_serialization_status wlan_ser_move_scan_pending_to_active( qdf_mem_copy(&cmd_to_remove, &pending_cmd_list->cmd, sizeof(struct wlan_serialization_command)); + if (!wlan_serialization_is_active_scan_cmd_allowed(&cmd_to_remove)) { + wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); + goto error; + } + qdf_status = wlan_ser_remove_scan_cmd(ser_pdev_obj, &pending_cmd_list, diff --git a/umac/cmn_services/serialization/src/wlan_serialization_scan_i.h b/umac/cmn_services/serialization/src/wlan_serialization_scan_i.h index 3e24ab35953a..375f3aaea3bf 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_scan_i.h +++ b/umac/cmn_services/serialization/src/wlan_serialization_scan_i.h @@ -50,6 +50,19 @@ void wlan_serialization_active_scan_cmd_count_handler(struct wlan_objmgr_psoc *psoc, void *obj, void *arg); +/** + * wlan_serialization_is_scan_pending_queue_empty() + * + * @cmd: Serialization command information + * + * This API will be find out if scan cmd pending queue is empty. + * + * Return: true or false + */ +bool +wlan_serialization_is_scan_pending_queue_empty( + struct wlan_serialization_command *cmd); + /** * wlan_serialization_is_active_scan_cmd_allowed() - find if scan cmd allowed * @pdev: pointer to pdev object