From 522eff91e576cc7a52c1f1467ad71c1d7417f627 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Tue, 28 Dec 2021 22:25:27 +0800 Subject: [PATCH] drivers: modem: gsm: Use dedicated workq The driver performs AT commands configurations using the system workqueue, this can delay the workqueue by up to 6 seconds to wait for the modem replies, which isn't ideal. This PR creates a dedicated workqueue for the gsm, and provides a helper function to reschedule work items to the gsm workqueue. Signed-off-by: Yong Cong Sin --- drivers/modem/Kconfig.gsm | 7 ++++++ drivers/modem/gsm_ppp.c | 45 ++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/drivers/modem/Kconfig.gsm b/drivers/modem/Kconfig.gsm index cc098c7f55e..adc630963fc 100644 --- a/drivers/modem/Kconfig.gsm +++ b/drivers/modem/Kconfig.gsm @@ -40,6 +40,13 @@ config MODEM_GSM_RX_STACK_SIZE help Sets the stack size which will be used by the GSM RX thread. +config MODEM_GSM_WORKQ_STACK_SIZE + int "Size of the stack allocated for the dedicated gsm workqueue" + default 768 + help + Sets the stack size which will be used by the dedicated GSM workqueue + thread. + config MODEM_GSM_INIT_PRIORITY int "Init priority for the GSM modem driver" default 42 diff --git a/drivers/modem/gsm_ppp.c b/drivers/modem/gsm_ppp.c index 59c6fc45e75..f76b6e2fd91 100644 --- a/drivers/modem/gsm_ppp.c +++ b/drivers/modem/gsm_ppp.c @@ -31,6 +31,7 @@ LOG_MODULE_REGISTER(modem_gsm, CONFIG_MODEM_LOG_LEVEL); #define GSM_CMD_AT_TIMEOUT K_SECONDS(2) #define GSM_CMD_SETUP_TIMEOUT K_SECONDS(6) #define GSM_RX_STACK_SIZE CONFIG_MODEM_GSM_RX_STACK_SIZE +#define GSM_WORKQ_STACK_SIZE CONFIG_MODEM_GSM_WORKQ_STACK_SIZE #define GSM_RECV_MAX_BUF 30 #define GSM_RECV_BUF_SIZE 128 #define GSM_ATTACH_RETRY_DELAY_MSEC 1000 @@ -96,11 +97,18 @@ static struct gsm_modem { NET_BUF_POOL_DEFINE(gsm_recv_pool, GSM_RECV_MAX_BUF, GSM_RECV_BUF_SIZE, 0, NULL); K_KERNEL_STACK_DEFINE(gsm_rx_stack, GSM_RX_STACK_SIZE); +K_THREAD_STACK_DEFINE(gsm_workq_stack, GSM_WORKQ_STACK_SIZE); struct k_thread gsm_rx_thread; +static struct k_work_q gsm_workq; static struct k_work_delayable rssi_work_handle; static struct gsm_ppp_modem_info minfo; +static inline int gsm_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay) +{ + return k_work_reschedule_for_queue(&gsm_workq, dwork, delay); +} + #if defined(CONFIG_MODEM_GSM_ENABLE_CESQ_RSSI) /* helper macro to keep readability */ #define ATOI(s_, value_, desc_) modem_atoi(s_, value_, desc_, __func__) @@ -580,9 +588,10 @@ static void rssi_handler(struct k_work *work) #if defined(CONFIG_GSM_MUX) #if defined(CONFIG_MODEM_CELL_INFO) - (void) gsm_query_cellinfo(&gsm); + (void)gsm_query_cellinfo(&gsm); #endif - k_work_reschedule(&rssi_work_handle, K_SECONDS(CONFIG_MODEM_GSM_RSSI_POLLING_PERIOD)); + (void)gsm_work_reschedule(&rssi_work_handle, + K_SECONDS(CONFIG_MODEM_GSM_RSSI_POLLING_PERIOD)); #endif } @@ -611,7 +620,7 @@ static void gsm_finalize_connection(struct gsm_modem *gsm) if (ret < 0) { LOG_ERR("modem setup returned %d, %s", ret, "retrying..."); - (void)k_work_reschedule(&gsm->gsm_configure_work, + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_SECONDS(1)); return; } @@ -633,7 +642,7 @@ static void gsm_finalize_connection(struct gsm_modem *gsm) LOG_ERR("modem setup returned %d, %s", ret, "retrying..."); - (void)k_work_reschedule(&gsm->gsm_configure_work, + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_SECONDS(1)); return; } @@ -647,14 +656,14 @@ static void gsm_finalize_connection(struct gsm_modem *gsm) if (ret < 0) { LOG_DBG("modem setup returned %d, %s", ret, "retrying..."); - (void)k_work_reschedule(&gsm->gsm_configure_work, K_SECONDS(1)); + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_SECONDS(1)); return; } ret = gsm_query_modem_info(gsm); if (ret < 0) { LOG_DBG("Unable to query modem information %d", ret); - (void)k_work_reschedule(&gsm->gsm_configure_work, K_SECONDS(1)); + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_SECONDS(1)); return; } @@ -681,7 +690,7 @@ attaching: LOG_DBG("Not attached, %s", "retrying..."); - (void)k_work_reschedule(&gsm->gsm_configure_work, + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_MSEC(GSM_ATTACH_RETRY_DELAY_MSEC)); return; } @@ -704,13 +713,13 @@ attaching: LOG_DBG("Not valid RSSI, %s", "retrying..."); if (gsm->rssi_retries-- > 0) { - (void)k_work_reschedule(&gsm->gsm_configure_work, + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_MSEC(GSM_RSSI_RETRY_DELAY_MSEC)); return; } } #if defined(CONFIG_MODEM_CELL_INFO) - (void) gsm_query_cellinfo(gsm); + (void)gsm_query_cellinfo(gsm); #endif } @@ -725,7 +734,7 @@ attaching: if (ret < 0) { LOG_DBG("modem setup returned %d, %s", ret, "retrying..."); - (void)k_work_reschedule(&gsm->gsm_configure_work, K_SECONDS(1)); + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_SECONDS(1)); return; } @@ -821,7 +830,7 @@ static int mux_enable(struct gsm_modem *gsm) static void mux_setup_next(struct gsm_modem *gsm) { - (void)k_work_reschedule(&gsm->gsm_configure_work, K_MSEC(1)); + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_MSEC(1)); } static void mux_attach_cb(const struct device *mux, int dlci_address, @@ -976,7 +985,7 @@ static void gsm_configure(struct k_work *work) if (ret < 0) { LOG_DBG("modem not ready %d", ret); - (void)k_work_reschedule(&gsm->gsm_configure_work, K_NO_WAIT); + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_NO_WAIT); return; } @@ -990,7 +999,7 @@ static void gsm_configure(struct k_work *work) gsm->mux_enabled = true; } else { gsm->mux_enabled = false; - (void)k_work_reschedule(&gsm->gsm_configure_work, + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_NO_WAIT); return; } @@ -1004,7 +1013,7 @@ static void gsm_configure(struct k_work *work) k_work_init_delayable(&gsm->gsm_configure_work, mux_setup); - (void)k_work_reschedule(&gsm->gsm_configure_work, + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_NO_WAIT); return; } @@ -1026,7 +1035,7 @@ void gsm_ppp_start(const struct device *dev) } k_work_init_delayable(&gsm->gsm_configure_work, gsm_configure); - (void)k_work_reschedule(&gsm->gsm_configure_work, K_NO_WAIT); + (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_NO_WAIT); #if defined(CONFIG_GSM_MUX) k_work_init_delayable(&rssi_work_handle, rssi_handler); @@ -1144,6 +1153,12 @@ static int gsm_init(const struct device *dev) gsm, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); k_thread_name_set(&gsm_rx_thread, "gsm_rx"); + /* initialize the work queue */ + k_work_queue_init(&gsm_workq); + k_work_queue_start(&gsm_workq, gsm_workq_stack, K_THREAD_STACK_SIZEOF(gsm_workq_stack), + K_PRIO_COOP(7), NULL); + k_thread_name_set(&gsm_workq.thread, "gsm_workq"); + gsm->iface = ppp_net_if(); if (!gsm->iface) { LOG_ERR("Couldn't find ppp net_if!");