From bfd50437fd81c60331cb7e9556114b8e6cb8b080 Mon Sep 17 00:00:00 2001 From: Shashikala Prabhu Date: Tue, 20 Nov 2018 17:53:05 +0530 Subject: [PATCH] qcacmn: Use UNBOUND flag to create WMI RX workqueue WMI RX workqueue is created with WQ_MEM_RECLAIM flag. When host receives the WMI service ready event it queues the work. There is 50sec delay in scheduling workqueue to process WMI service ready event. This results in host timeout (timeout = 15sec) and wifi load failure. This cleans up the host data structures related to data path. But work got scheduled after 50sec resulting in init path handling with inconsistent data structures. Use workqueue UNBOUND flag to create WMI RX workqueue. Works queued to unbound workqueues are implicitly HIGHPRI and dispatched to unbound workers as soon as resources are available. Change-Id: I46eb0242ad88103268df99be9fd2e0759ebec4b2 CRs-Fixed: 2343181 --- qdf/inc/qdf_defer.h | 13 ++++++++++++- qdf/linux/src/i_qdf_defer.h | 11 +++++++++++ wmi/src/wmi_unified.c | 4 ++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/qdf/inc/qdf_defer.h b/qdf/inc/qdf_defer.h index a10ca2e16b..2b0f418584 100644 --- a/qdf/inc/qdf_defer.h +++ b/qdf/inc/qdf_defer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -142,6 +142,17 @@ static inline qdf_workqueue_t *qdf_create_singlethread_workqueue(char *name) return __qdf_create_singlethread_workqueue(name); } +/** + * qdf_alloc_unbound_workqueue - allocate an unbound workqueue + * @name: string + * + * Return: pointer of type qdf_workqueue_t + */ +static inline qdf_workqueue_t *qdf_alloc_unbound_workqueue(char *name) +{ + return __qdf_alloc_unbound_workqueue(name); +} + /** * qdf_queue_work - Queue the work/task * @hdl: OS handle diff --git a/qdf/linux/src/i_qdf_defer.h b/qdf/linux/src/i_qdf_defer.h index 4ce9fa1d9b..28209f5ca9 100644 --- a/qdf/linux/src/i_qdf_defer.h +++ b/qdf/linux/src/i_qdf_defer.h @@ -216,6 +216,17 @@ static inline __qdf_workqueue_t *__qdf_create_singlethread_workqueue(char *name) return create_singlethread_workqueue(name); } +/** + * __qdf_alloc_unbound_workqueue - alloc an unbound workqueue + * @name: string + * + * Return: pointer of type qdf_workqueue_t + */ +static inline __qdf_workqueue_t *__qdf_alloc_unbound_workqueue(char *name) +{ + return alloc_workqueue(name, WQ_UNBOUND, 0); +} + /** * __qdf_flush_workqueue - flush the workqueue * @wqueue: pointer to workqueue diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c index f6ab4595ac..4fc6b9b97e 100644 --- a/wmi/src/wmi_unified.c +++ b/wmi/src/wmi_unified.c @@ -2440,7 +2440,7 @@ void *wmi_unified_get_pdev_handle(struct wmi_soc *soc, uint32_t pdev_idx) qdf_create_work(0, &wmi_handle->rx_event_work, wmi_rx_event_work, wmi_handle); wmi_handle->wmi_rx_work_queue = - qdf_create_workqueue("wmi_rx_event_work_queue"); + qdf_alloc_unbound_workqueue("wmi_rx_event_work_queue"); if (NULL == wmi_handle->wmi_rx_work_queue) { WMI_LOGE("failed to create wmi_rx_event_work_queue"); goto error; @@ -2570,7 +2570,7 @@ void *wmi_unified_attach(void *scn_handle, qdf_create_work(0, &wmi_handle->rx_event_work, wmi_rx_event_work, wmi_handle); wmi_handle->wmi_rx_work_queue = - qdf_create_workqueue("wmi_rx_event_work_queue"); + qdf_alloc_unbound_workqueue("wmi_rx_event_work_queue"); if (NULL == wmi_handle->wmi_rx_work_queue) { WMI_LOGE("failed to create wmi_rx_event_work_queue"); goto error;