From 0f993fe32fbccf4cf33055b56e6d0480a624d29e Mon Sep 17 00:00:00 2001 From: Vivek Date: Sun, 9 Dec 2018 17:21:04 +0530 Subject: [PATCH] qcacmn: Disbale serialization vdev queues on demand Add new attribute to the serialization command structure to disable the vdev queues on queuing the given command. The serialization command attribute to disable queues is only used for non scan commands. After the queues are disabled, new serialization requests applicable for the given vdev will not be allowed. Change-Id: I29e6330413e9b16c7d3e96ad0eb004515061db88 CRs-Fixed: 2349901 --- .../inc/wlan_serialization_api.h | 5 ++ .../src/wlan_serialization_internal.c | 49 +++++++++++++++++++ .../src/wlan_serialization_queue.c | 9 ++++ .../src/wlan_serialization_utils_i.h | 2 + 4 files changed, 65 insertions(+) diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h index f8430fe9c253..8cec6fbe7a52 100644 --- a/umac/cmn_services/serialization/inc/wlan_serialization_api.h +++ b/umac/cmn_services/serialization/inc/wlan_serialization_api.h @@ -661,6 +661,7 @@ enum wlan_serialization_cancel_type { * @WLAN_SER_CMD_ACTIVE: Command is activated and put in active queue * @WLAN_SER_CMD_DENIED_RULES_FAILED: Command denied as the rules fail * @WLAN_SER_CMD_DENIED_LIST_FULL: Command denied as the pending list is full + * @WLAN_SER_CMD_QUEUE_DISABLED: Command denied as the queue is disabled * @WLAN_SER_CMD_DENIED_UNSPECIFIED: Command denied due to unknown reason */ enum wlan_serialization_status { @@ -668,6 +669,7 @@ enum wlan_serialization_status { WLAN_SER_CMD_ACTIVE, WLAN_SER_CMD_DENIED_RULES_FAILED, WLAN_SER_CMD_DENIED_LIST_FULL, + WLAN_SER_CMD_QUEUE_DISABLED, WLAN_SER_CMD_DENIED_UNSPECIFIED, }; @@ -694,6 +696,8 @@ enum wlan_serialization_cmd_status { * @cmd_cb: Command callback * @source: component ID of the source of the command * @is_high_priority: Normal/High Priority at which the cmd has to be queued + * @is_blocking: Is the command blocking + * @queue_disable: Should the command disable the queues * @cmd_timeout_cb: Command timeout callback * @cmd_timeout_duration: Timeout duration in milliseconds * @vdev: VDEV object associated to the command @@ -710,6 +714,7 @@ struct wlan_serialization_command { enum wlan_umac_comp_id source; bool is_high_priority; bool is_blocking; + bool queue_disable; uint16_t cmd_timeout_duration; union { struct wlan_objmgr_vdev *vdev; diff --git a/umac/cmn_services/serialization/src/wlan_serialization_internal.c b/umac/cmn_services/serialization/src/wlan_serialization_internal.c index f4eeb83171e0..7797fda6a65b 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_internal.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_internal.c @@ -95,6 +95,8 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd, struct wlan_objmgr_pdev *pdev; struct wlan_ser_pdev_obj *ser_pdev_obj; struct wlan_serialization_pdev_queue *pdev_queue; + struct wlan_ser_vdev_obj *ser_vdev_obj; + struct wlan_serialization_vdev_queue *vdev_queue; bool active_queue; /* Enqueue process @@ -167,6 +169,53 @@ wlan_serialization_enqueue_cmd(struct wlan_serialization_command *cmd, wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); + /* Before queuing any non scan command, + * as part of wlan_serialization_request, + * we check if the vdev queues are disabled. + * + * The serialization command structure has an + * attribute, where after a given command is queued, + * we can block the vdev queues. + * + * For example, after VDEV_DOWN command is queued as + * part of a vdev deletion, no other commands should be queued + * until the deletion is complete, so with VDEV_DOWN(in case of + * vdev deletion) with pass the attribute to disable vdev queues + */ + if (cmd->cmd_type > WLAN_SER_CMD_SCAN && + ser_reason == SER_REQUEST) { + ser_vdev_obj = + wlan_serialization_get_vdev_obj( + wlan_serialization_get_vdev_from_cmd(cmd)); + + if (!ser_vdev_obj) { + wlan_serialization_release_lock( + &pdev_queue->pdev_queue_lock); + goto error; + } + + vdev_queue = + wlan_serialization_get_vdev_queue_obj( + ser_vdev_obj, + cmd->cmd_type); + + if (!vdev_queue) { + wlan_serialization_release_lock( + &pdev_queue->pdev_queue_lock); + goto error; + } + + if (vdev_queue->queue_disable) { + wlan_serialization_release_lock( + &pdev_queue->pdev_queue_lock); + ser_err("VDEV queue is disabled, ser request denied"); + ser_err("cmd id[%d] cmd type[%d]", cmd->cmd_id, + cmd->cmd_type); + status = WLAN_SER_CMD_QUEUE_DISABLED; + goto error; + } + } + active_queue = wlan_serialization_is_active_cmd_allowed(cmd); if (wlan_serialization_is_cmd_present_queue(cmd, active_queue)) { diff --git a/umac/cmn_services/serialization/src/wlan_serialization_queue.c b/umac/cmn_services/serialization/src/wlan_serialization_queue.c index 374529b66e38..d4d23679267a 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_queue.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_queue.c @@ -126,12 +126,18 @@ wlan_serialization_add_cmd_to_vdev_queue( enum wlan_serialization_status status; struct wlan_serialization_command *cmd; struct wlan_ser_vdev_obj *vdev_obj; + struct wlan_serialization_vdev_queue *vdev_queue_obj; cmd = &cmd_list->cmd; vdev_obj = wlan_serialization_get_vdev_obj( wlan_serialization_get_vdev_from_cmd(cmd)); + vdev_queue_obj = + wlan_serialization_get_vdev_queue_obj( + vdev_obj, + cmd->cmd_type); + queue = wlan_serialization_get_list_from_vdev_queue(vdev_obj, cmd->cmd_type, for_active_queue); @@ -141,6 +147,9 @@ wlan_serialization_add_cmd_to_vdev_queue( for_active_queue, WLAN_SER_VDEV_NODE); + if (cmd->queue_disable) + vdev_queue_obj->queue_disable = true; + return 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 c4c7623f06c7..af6dd61f1e43 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h +++ b/umac/cmn_services/serialization/src/wlan_serialization_utils_i.h @@ -720,10 +720,12 @@ struct wlan_serialization_pdev_queue { * struct wlan_serialization_vdev_queue - queue data related to vdev * @active_list: list to hold the commands currently being executed * @pending_list list: to hold the commands currently pending + * @queue_disable: is the queue disabled */ struct wlan_serialization_vdev_queue { qdf_list_t active_list; qdf_list_t pending_list; + bool queue_disable; }; /**