qcacmn: Make access to serialization timers atomic

The serialization timers can be accessed from multiple contexts
when adding and removing commands to/from the serialization
queues. So the access to the serialization timers should be
atomic to protect the same timers being used for multiple
commands.

The serialization timers are maintained per psoc and are
protected with psoc timer locks.

Also the serialization lock APIs are updated to take the lock
object pointer as an argument

Change-Id: Ibdb41818fde9318fca6bbc92a536858364639365
CRs-Fixed: 2313039
This commit is contained in:
Vivek
2018-09-12 15:44:14 +05:30
committed by nshrivas
parent fea1a84116
commit aa6303e509
7 changed files with 76 additions and 77 deletions

View File

@@ -617,7 +617,7 @@ wlan_serialization_non_scan_cmd_status(
/* Look in the pdev non scan active queue */
queue = &pdev_q->active_list;
wlan_serialization_acquire_lock(pdev_q);
wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
node = wlan_serialization_find_cmd(
queue, WLAN_SER_MATCH_CMD_TYPE,
@@ -641,7 +641,7 @@ wlan_serialization_non_scan_cmd_status(
cmd_status = wlan_serialization_is_cmd_in_active_pending(
cmd_in_active, cmd_in_pending);
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
ser_exit();
return cmd_status;
@@ -813,7 +813,7 @@ wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev)
pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
wlan_serialization_acquire_lock(pdev_q);
wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
cmd_in_active =
wlan_serialization_is_cmd_in_vdev_list(
@@ -826,7 +826,7 @@ wlan_serialization_vdev_scan_status(struct wlan_objmgr_vdev *vdev)
status = wlan_serialization_is_cmd_in_active_pending(
cmd_in_active, cmd_in_pending);
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
ser_exit();
return status;
@@ -857,7 +857,7 @@ wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev)
pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
wlan_serialization_acquire_lock(pdev_q);
wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
cmd_in_active = !qdf_list_empty(&pdev_q->active_list);
cmd_in_pending = !qdf_list_empty(&pdev_q->pending_list);
@@ -865,7 +865,7 @@ wlan_serialization_pdev_scan_status(struct wlan_objmgr_pdev *pdev)
status = wlan_serialization_is_cmd_in_active_pending(
cmd_in_active, cmd_in_pending);
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
return status;
}
@@ -910,7 +910,7 @@ wlan_serialization_get_scan_cmd_using_scan_id(
pdev_q = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
wlan_serialization_acquire_lock(pdev_q);
wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
if (is_scan_cmd_from_active_queue)
queue = &pdev_q->active_list;
@@ -931,7 +931,7 @@ wlan_serialization_get_scan_cmd_using_scan_id(
}
}
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
release_vdev_ref:
wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);
@@ -980,7 +980,7 @@ void *wlan_serialization_get_active_cmd(
pdev_q = wlan_serialization_get_pdev_queue_obj(ser_pdev_obj, cmd_type);
wlan_serialization_acquire_lock(pdev_q);
wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
queue = &pdev_q->active_list;
@@ -997,7 +997,7 @@ void *wlan_serialization_get_active_cmd(
umac_cmd = cmd_list->cmd.umac_cmd;
}
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
release_vdev_ref:
wlan_objmgr_vdev_release_ref(vdev, WLAN_SERIALIZATION_ID);

View File

@@ -164,12 +164,12 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd)
cmd->is_high_priority,
cmd->is_blocking);
wlan_serialization_acquire_lock(pdev_queue);
wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
active_queue = wlan_serialization_is_active_cmd_allowed(cmd);
if (wlan_serialization_is_cmd_present_queue(cmd, active_queue)) {
wlan_serialization_release_lock(pdev_queue);
wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
ser_err("duplicate command, can't enqueue");
goto error;
}
@@ -177,7 +177,7 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd)
if (wlan_serialization_remove_front(
&pdev_queue->cmd_pool_list,
&nnode) != QDF_STATUS_SUCCESS) {
wlan_serialization_release_lock(pdev_queue);
wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
ser_err("Failed to get cmd buffer from global pool");
goto error;
}
@@ -216,7 +216,7 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd)
&cmd_list->cmd_in_use);
}
wlan_serialization_release_lock(pdev_queue);
wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
if (WLAN_SER_CMD_ACTIVE == status)
wlan_serialization_activate_cmd(cmd_list,
@@ -463,7 +463,7 @@ wlan_serialization_dequeue_cmd(struct wlan_serialization_command *cmd,
cmd->is_high_priority,
cmd->is_blocking);
wlan_serialization_acquire_lock(pdev_queue);
wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
if (cmd->cmd_type < WLAN_SER_CMD_NONSCAN)
qdf_status = wlan_ser_remove_scan_cmd(
@@ -474,7 +474,7 @@ wlan_serialization_dequeue_cmd(struct wlan_serialization_command *cmd,
}
if (qdf_status != QDF_STATUS_SUCCESS) {
wlan_serialization_release_lock(pdev_queue);
wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
status = WLAN_SER_CMD_NOT_FOUND;
goto error;
}
@@ -520,7 +520,7 @@ wlan_serialization_dequeue_cmd(struct wlan_serialization_command *cmd,
blocking_cmd_waiting);
}
wlan_serialization_release_lock(pdev_queue);
wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
/* Call cmd cb for remove request*/
if (cmd_bkup.cmd_cb) {
@@ -674,6 +674,8 @@ wlan_serialization_find_and_stop_timer(struct wlan_objmgr_psoc *psoc,
* be unique and For non-scan command, there should be only one active
* command per pdev
*/
wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
ser_timer = &psoc_ser_obj->timers[i];
if (!(ser_timer->cmd) ||
@@ -681,14 +683,21 @@ wlan_serialization_find_and_stop_timer(struct wlan_objmgr_psoc *psoc,
(ser_timer->cmd->cmd_type != cmd->cmd_type) ||
(ser_timer->cmd->vdev != cmd->vdev))
continue;
status = wlan_serialization_stop_timer(ser_timer);
ser_debug("\n Stopping timer for cmd type:%d, id: %d",
cmd->cmd_type, cmd->cmd_id);
status = QDF_STATUS_SUCCESS;
break;
}
if (QDF_STATUS_SUCCESS != status)
wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
if (QDF_IS_STATUS_SUCCESS(status)) {
status = wlan_serialization_stop_timer(ser_timer);
ser_debug("\n Stopping timer for cmd type:%d, id: %d",
cmd->cmd_type, cmd->cmd_id);
} else {
ser_err("Can't find timer for cmd_type[%d]", cmd->cmd_type);
}
error:
exit:
@@ -721,6 +730,8 @@ wlan_serialization_find_and_start_timer(struct wlan_objmgr_psoc *psoc,
psoc_ser_obj = wlan_serialization_get_psoc_obj(psoc);
wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
/* Keep trying timer */
ser_timer = &psoc_ser_obj->timers[i];
@@ -729,6 +740,13 @@ wlan_serialization_find_and_start_timer(struct wlan_objmgr_psoc *psoc,
/* Remember timer is pointing to command */
ser_timer->cmd = cmd;
status = QDF_STATUS_SUCCESS;
break;
}
wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
if (QDF_IS_STATUS_SUCCESS(status)) {
qdf_timer_init(NULL,
&ser_timer->timer,
wlan_serialization_timer_handler,
@@ -742,9 +760,6 @@ wlan_serialization_find_and_start_timer(struct wlan_objmgr_psoc *psoc,
cmd->cmd_id,
cmd->is_high_priority,
cmd->is_blocking);
status = QDF_STATUS_SUCCESS;
break;
}
error:

View File

@@ -520,6 +520,7 @@ QDF_STATUS wlan_serialization_psoc_close(struct wlan_objmgr_psoc *psoc)
ser_soc_obj->timers = NULL;
ser_soc_obj->max_active_cmds = 0;
wlan_serialization_destroy_lock(&ser_soc_obj->timer_lock);
error:
ser_exit();
return status;
@@ -550,6 +551,7 @@ QDF_STATUS wlan_serialization_psoc_open(struct wlan_objmgr_psoc *psoc)
goto error;
}
wlan_serialization_create_lock(&ser_soc_obj->timer_lock);
status = QDF_STATUS_SUCCESS;
error:
@@ -708,7 +710,7 @@ static QDF_STATUS wlan_serialization_pdev_create_handler(
for (index = 0; index < SER_PDEV_QUEUE_COMP_MAX; index++) {
pdev_queue = &ser_pdev_obj->pdev_q[index];
qdf_spinlock_create(&pdev_queue->pdev_queue_lock);
wlan_serialization_create_lock(&pdev_queue->pdev_queue_lock);
switch (index) {
case SER_PDEV_QUEUE_COMP_SCAN:
@@ -825,7 +827,7 @@ static QDF_STATUS wlan_serialization_pdev_destroy_handler(
wlan_serialization_destroy_pdev_list(pdev_queue);
wlan_serialization_destroy_cmd_pool(pdev_queue);
qdf_spinlock_destroy(&pdev_queue->pdev_queue_lock);
wlan_serialization_destroy_lock(&pdev_queue->pdev_queue_lock);
}
qdf_mem_free(ser_pdev_obj);

View File

@@ -498,7 +498,7 @@ wlan_ser_cancel_non_scan_cmd(
else
ser_debug("Can't find psoc");
wlan_serialization_acquire_lock(pdev_q);
wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
qsize = wlan_serialization_list_size(pdev_queue);
while (!wlan_serialization_list_empty(pdev_queue) && qsize--) {
@@ -554,7 +554,8 @@ wlan_ser_cancel_non_scan_cmd(
*/
if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION,
&cmd_list->cmd_in_use)) {
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(
&pdev_q->pdev_queue_lock);
status = WLAN_SER_CMD_MARKED_FOR_ACTIVATION;
goto error;
}
@@ -607,7 +608,7 @@ wlan_ser_cancel_non_scan_cmd(
}
nnode = pnode;
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
/*
* call pending cmd's callback to notify that
* it is being removed
@@ -626,7 +627,7 @@ wlan_ser_cancel_non_scan_cmd(
WLAN_SER_CB_RELEASE_MEM_CMD);
}
wlan_serialization_acquire_lock(pdev_q);
wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
if (!is_active_queue)
status = WLAN_SER_CMD_IN_PENDING_LIST;
@@ -635,7 +636,7 @@ wlan_ser_cancel_non_scan_cmd(
break;
}
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
error:
ser_exit();

View File

@@ -186,7 +186,7 @@ wlan_ser_cancel_scan_cmd(
else
ser_debug("Can't find psoc");
wlan_serialization_acquire_lock(pdev_q);
wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
qsize = wlan_serialization_list_size(queue);
while (!wlan_serialization_list_empty(queue) && qsize--) {
@@ -242,7 +242,8 @@ wlan_ser_cancel_scan_cmd(
*/
if (qdf_atomic_test_bit(CMD_MARKED_FOR_ACTIVATION,
&cmd_list->cmd_in_use)) {
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(
&pdev_q->pdev_queue_lock);
status = WLAN_SER_CMD_MARKED_FOR_ACTIVATION;
goto error;
}
@@ -284,7 +285,7 @@ wlan_ser_cancel_scan_cmd(
}
nnode = pnode;
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
/*
* call pending cmd's callback to notify that
* it is being removed
@@ -303,13 +304,13 @@ wlan_ser_cancel_scan_cmd(
WLAN_SER_CB_RELEASE_MEM_CMD);
}
wlan_serialization_acquire_lock(pdev_q);
wlan_serialization_acquire_lock(&pdev_q->pdev_queue_lock);
if (!is_active_queue)
status = WLAN_SER_CMD_IN_PENDING_LIST;
}
wlan_serialization_release_lock(pdev_q);
wlan_serialization_release_lock(&pdev_q->pdev_queue_lock);
error:
ser_exit();

View File

@@ -1140,6 +1140,8 @@ QDF_STATUS wlan_serialization_cleanup_all_timers(
goto error;
}
wlan_serialization_acquire_lock(&psoc_ser_obj->timer_lock);
for (i = 0; psoc_ser_obj->max_active_cmds > i; i++) {
ser_timer = &psoc_ser_obj->timers[i];
if (!ser_timer->cmd)
@@ -1151,6 +1153,7 @@ QDF_STATUS wlan_serialization_cleanup_all_timers(
}
}
wlan_serialization_release_lock(&psoc_ser_obj->timer_lock);
error:
ser_exit();
return status;
@@ -1783,53 +1786,33 @@ error:
}
QDF_STATUS
wlan_serialization_acquire_lock(
struct wlan_serialization_pdev_queue *pdev_queue)
wlan_serialization_acquire_lock(qdf_spinlock_t *lock)
{
if (!pdev_queue) {
ser_err("invalid object");
return QDF_STATUS_E_FAILURE;
}
qdf_spin_lock_bh(&pdev_queue->pdev_queue_lock);
qdf_spin_lock_bh(lock);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_serialization_release_lock(
struct wlan_serialization_pdev_queue *pdev_queue)
wlan_serialization_release_lock(qdf_spinlock_t *lock)
{
if (!pdev_queue) {
ser_err("invalid object");
return QDF_STATUS_E_FAILURE;
}
qdf_spin_unlock_bh(&pdev_queue->pdev_queue_lock);
qdf_spin_unlock_bh(lock);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_serialization_create_lock(
struct wlan_serialization_pdev_queue *pdev_queue)
wlan_serialization_create_lock(qdf_spinlock_t *lock)
{
if (!pdev_queue) {
ser_err("invalid object");
return QDF_STATUS_E_FAILURE;
}
qdf_spinlock_create(&pdev_queue->pdev_queue_lock);
qdf_spinlock_create(lock);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
wlan_serialization_destroy_lock(
struct wlan_serialization_pdev_queue *pdev_queue)
wlan_serialization_destroy_lock(qdf_spinlock_t *lock)
{
if (!pdev_queue) {
ser_err("invalid object");
return QDF_STATUS_E_FAILURE;
}
qdf_spinlock_destroy(&pdev_queue->pdev_queue_lock);
qdf_spinlock_destroy(lock);
return QDF_STATUS_SUCCESS;
}

View File

@@ -784,6 +784,7 @@ struct wlan_ser_psoc_obj {
wlan_serialization_apply_rules_cb apply_rules_cb[WLAN_SER_CMD_MAX];
struct wlan_serialization_timer *timers;
uint8_t max_active_cmds;
qdf_spinlock_t timer_lock;
};
/**
@@ -1202,42 +1203,38 @@ QDF_STATUS wlan_serialization_peek_next(
/**
* wlan_serialization_acquire_lock() - Acquire lock to the given queue
* @pdev_queue: Pointer to the pdev queue
* @lock: Pointer to the lock
*
* Return: QDF_STATUS success or failure
*/
QDF_STATUS
wlan_serialization_acquire_lock(
struct wlan_serialization_pdev_queue *pdev_queue);
wlan_serialization_acquire_lock(qdf_spinlock_t *lock);
/**
* wlan_serialization_release_lock() - Release lock to the given queue
* @pdev_queue: Pointer to the pdev queue
* @lock: Pointer to the lock
*
* Return: QDF_STATUS success or failure
*/
QDF_STATUS
wlan_serialization_release_lock(
struct wlan_serialization_pdev_queue *pdev_queue);
wlan_serialization_release_lock(qdf_spinlock_t *lock);
/**
* wlan_serialization_create_lock() - Init the lock to the given queue
* @pdev_queue: Pointer to the pdev queue
* @lock: Pointer to the lock
*
* Return: QDF_STATUS success or failure
*/
QDF_STATUS
wlan_serialization_create_lock(
struct wlan_serialization_pdev_queue *pdev_queue);
wlan_serialization_create_lock(qdf_spinlock_t *lock);
/**
* wlan_serialization_destroy_lock() - Deinit the lock to the given queue
* @pdev_queue: Pointer to the pdev queue
* @lock: Pointer to the lock
*
* Return: QDF_STATUS success or failure
*/
QDF_STATUS
wlan_serialization_destroy_lock(
struct wlan_serialization_pdev_queue *pdev_queue);
wlan_serialization_destroy_lock(qdf_spinlock_t *lock);
#endif
#endif