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
This commit is contained in:
Vivek 2018-12-09 17:10:08 +05:30 • committed by nshrivas
commit c3357683fa
3 changed files with 28 additions and 5 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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