From c3357683fa9a033f27794becb0288ec50a6e363a Mon Sep 17 00:00:00 2001 From: Vivek Date: Sun, 9 Dec 2018 17:10:08 +0530 Subject: [PATCH] qcacmn: Avoid active command removal until activation completes With the current implementation, the removal of a command is allowed before the activation cb returns. So if a command is removed before the activation returns, and the activation returns failure, we attempt to access the command buffer after the cmd is removed happen. This is now protected by a new flag where if a removal is attempted before a commands activation cb is completed the removal request just marks the CMD_MARKED_FOR_REMOVAL flag and when the activation cb returns, we check if a commands removal had been attempted. If yes, remove the command from the active queue. Change-Id: I53af6706010b50640ea7248085e9fc85908056fa CRs-Fixed: 2356813 --- .../src/wlan_serialization_internal.c | 18 ++++++++++++++++-- .../src/wlan_serialization_utils.c | 8 ++++++++ .../src/wlan_serialization_utils_i.h | 7 ++++--- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/umac/cmn_services/serialization/src/wlan_serialization_internal.c b/umac/cmn_services/serialization/src/wlan_serialization_internal.c index 6c30a94cc6fd..f4eeb83171e0 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_internal.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_internal.c @@ -290,10 +290,18 @@ QDF_STATUS wlan_serialization_activate_cmd( } /* - * Cmd was marked for activation and cancel - * was received before activation so the command + * Cmd was marked for activation and delete or cancel + * is received before activation completed, then the command * should be immediately removed after activation */ + if (qdf_atomic_test_bit(CMD_ACTIVE_MARKED_FOR_REMOVAL, + &cmd_list->cmd_in_use)) { + wlan_serialization_dequeue_cmd(&cmd_list->cmd, + SER_REMOVE, + true); + return status; + } + if (qdf_atomic_test_bit(CMD_ACTIVE_MARKED_FOR_CANCEL, &cmd_list->cmd_in_use)) wlan_serialization_cmd_cancel_handler( @@ -421,6 +429,12 @@ wlan_serialization_dequeue_cmd(struct wlan_serialization_command *cmd, ser_pdev_obj, &cmd_list, cmd, active_cmd); } + if (qdf_status == QDF_STATUS_E_PENDING) { + status = WLAN_SER_CMD_MARKED_FOR_ACTIVATION; + wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); + goto error; + } + if (qdf_status != QDF_STATUS_SUCCESS) { wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); status = WLAN_SER_CMD_NOT_FOUND; diff --git a/umac/cmn_services/serialization/src/wlan_serialization_utils.c b/umac/cmn_services/serialization/src/wlan_serialization_utils.c index 66081b55119d..2ba6995201a8 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_utils.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils.c @@ -1425,6 +1425,14 @@ wlan_serialization_remove_cmd_from_queue( cmd_list->cmd.is_high_priority, cmd_list->cmd.is_blocking); + if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION, + &cmd_list->cmd_in_use)) { + qdf_atomic_set_bit(CMD_ACTIVE_MARKED_FOR_REMOVAL, + &cmd_list->cmd_in_use); + status = QDF_STATUS_E_PENDING; + goto error; + } + status = wlan_serialization_remove_node(queue, node); if (QDF_STATUS_SUCCESS != status) diff --git a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h index dc76e5d598e5..c4c7623f06c7 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h @@ -646,9 +646,10 @@ enum ser_queue_reason { * CMD_MARKED_FOR_ACTIVATION - The command is about to be activated * CMD_IS_ACTIVE - The command is active and currently in use */ -#define CMD_MARKED_FOR_ACTIVATION 1 -#define CMD_IS_ACTIVE 2 -#define CMD_ACTIVE_MARKED_FOR_CANCEL 3 +#define CMD_MARKED_FOR_ACTIVATION 1 +#define CMD_IS_ACTIVE 2 +#define CMD_ACTIVE_MARKED_FOR_CANCEL 3 +#define CMD_ACTIVE_MARKED_FOR_REMOVAL 4 /** * struct wlan_serialization_timer - Timer used for serialization * @cmd: Cmd to which the timer is linked