Skip to content

Commit f214440

Browse files
PoC: Add support to have an dedicated work queue per transport.
1 parent f791c49 commit f214440

File tree

5 files changed

+67
-18
lines changed

5 files changed

+67
-18
lines changed

include/zephyr/mgmt/mcumgr/transport/smp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ struct smp_transport {
132132
uint16_t expected; /* expected bytes to come */
133133
} __reassembly;
134134
#endif
135+
#ifdef CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_MODEL_DEDICATED
136+
/* Work queue for processing incoming requests */
137+
struct k_work_q work_queue;
138+
/* Work queue stack */
139+
K_KERNEL_STACK_MEMBER(work_queue_stack, CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE);
140+
#endif
135141
};
136142

137143
/**

subsys/mgmt/mcumgr/smp_client/src/client.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ static void smp_client_cmd_req_free(struct smp_client_cmd_req *cmd_req);
4949
/**
5050
* Send all SMP client request packets.
5151
*/
52-
static void smp_client_handle_reqs(struct k_work *work)
52+
static void smp_client_handle_reqs(struct k_work *work_)
5353
{
5454
struct smp_client_object *smp_client;
5555
struct smp_transport *smpt;
5656
struct net_buf *nb;
5757

58-
smp_client = (void *)work;
58+
smp_client = CONTAINER_OF(work_, struct smp_client_object, work);
5959
smpt = smp_client->smpt;
6060

6161
while ((nb = k_fifo_get(&smp_client->tx_fifo, K_NO_WAIT)) != NULL) {
@@ -112,7 +112,7 @@ static void smp_client_transport_work_fn(struct k_work *work)
112112
entry->retry_cnt--;
113113
entry->timestamp = time_stamp_ref + CONFIG_SMP_CMD_RETRY_TIME;
114114
k_fifo_put(&entry->smp_client->tx_fifo, entry->nb);
115-
k_work_submit_to_queue(smp_get_wq(), &entry->smp_client->work);
115+
k_work_submit_to_queue(smp_get_wq(entry->smp_client->smpt), &entry->smp_client->work);
116116
continue;
117117
}
118118

@@ -126,7 +126,7 @@ static void smp_client_transport_work_fn(struct k_work *work)
126126

127127
if (!sys_slist_is_empty(&smp_client_data.cmd_list)) {
128128
/* Re-schedule new timeout to next */
129-
k_work_reschedule_for_queue(smp_get_wq(), &smp_client_data.work_delay,
129+
k_work_reschedule_for_queue(NULL, &smp_client_data.work_delay,
130130
K_MSEC(backoff_ms));
131131
}
132132
}
@@ -161,7 +161,7 @@ static void smp_cmd_add_to_list(struct smp_client_cmd_req *cmd_req)
161161
{
162162
if (sys_slist_is_empty(&smp_client_data.cmd_list)) {
163163
/* Enable timer */
164-
k_work_reschedule_for_queue(smp_get_wq(), &smp_client_data.work_delay,
164+
k_work_reschedule_for_queue(smp_get_wq(cmd_req->smp_client->smpt), &smp_client_data.work_delay,
165165
K_MSEC(CONFIG_SMP_CMD_RETRY_TIME));
166166
}
167167
sys_slist_append(&smp_client_data.cmd_list, &cmd_req->node);
@@ -322,7 +322,7 @@ int smp_client_send_cmd(struct smp_client_object *smp_client, struct net_buf *nb
322322
nb = net_buf_ref(nb);
323323
smp_cmd_add_to_list(cmd_req);
324324
k_fifo_put(&smp_client->tx_fifo, nb);
325-
k_work_submit_to_queue(smp_get_wq(), &smp_client->work);
325+
k_work_submit_to_queue(smp_get_wq(smp_client->smpt), &smp_client->work);
326326
return MGMT_ERR_EOK;
327327
}
328328

subsys/mgmt/mcumgr/transport/Kconfig

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,29 @@
1111
# MCUMGR_TRANSPORT_ -- general transport options;
1212
# MCUMGR_TRANSPORT_WORKQUEUE -- for workqueue configuration;
1313
# MCUMGR_TRANSPORT_NETBUF -- for Net Buf related configuration.
14+
choice MCUMGR_TRANSPORT_WORKQUEUE_MODEL
15+
prompt "MCUmgr transport thread model"
16+
default MCUMGR_TRANSPORT_WORKQUEUE_MODEL_GLOBAL
17+
help
18+
Select the work queue model to be used by the MCUmgr transport
19+
subsystem.
20+
21+
config MCUMGR_TRANSPORT_WORKQUEUE_MODEL_DEDICATED
22+
bool "MCUmgr transport dedicated workqueue model"
23+
help
24+
The transport subsystem creates its own workqueue to handle
25+
incoming requests. This model is suitable for transports
26+
that require asynchronous processing of requests over
27+
multiple transport instances.
28+
29+
config MCUMGR_TRANSPORT_WORKQUEUE_MODEL_GLOBAL
30+
bool "MCUmgr transport global workqueue model"
31+
help
32+
The transport subsystem creates a global workqueue to handle
33+
incoming requests. This model is suitable for cases where a single
34+
workqueue services all transport instances.
35+
36+
endchoice
1437

1538
config MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE
1639
int "MCUmgr transport workqueue stack size"

subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,12 @@ struct zephyr_smp_transport;
4848
*/
4949
void smp_rx_req(struct smp_transport *smtp, struct net_buf *nb);
5050

51-
#ifdef CONFIG_SMP_CLIENT
5251
/**
5352
* @brief Get work queue for SMP client.
5453
*
5554
* @return SMP work queue object.
5655
*/
57-
struct k_work_q *smp_get_wq(void);
58-
#endif
56+
struct k_work_q *smp_get_wq(struct smp_transport *smpt);
5957

6058
/**
6159
* @brief Allocates a response buffer.

subsys/mgmt/mcumgr/transport/src/smp.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <zephyr/mgmt/mcumgr/smp/smp.h>
1414
#include <zephyr/mgmt/mcumgr/transport/smp.h>
1515

16+
#include <mgmt/mcumgr/transport/smp_internal.h>
1617
#include <mgmt/mcumgr/transport/smp_reassembly.h>
1718

1819
#include <zephyr/logging/log.h>
@@ -27,17 +28,20 @@ LOG_MODULE_REGISTER(mcumgr_smp, CONFIG_MCUMGR_TRANSPORT_LOG_LEVEL);
2728
#define WEAK
2829
#endif
2930

31+
#ifdef CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_MODEL_GLOBAL
3032
K_THREAD_STACK_DEFINE(smp_work_queue_stack, CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE);
3133

3234
static struct k_work_q smp_work_queue;
35+
#endif /* CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_MODEL_GLOBAL */
36+
37+
static const struct k_work_queue_config smp_work_queue_config = {
38+
.name = "mcumgr smp"
39+
};
3340

3441
#ifdef CONFIG_SMP_CLIENT
3542
static sys_slist_t smp_transport_clients = SYS_SLIST_STATIC_INIT(&smp_transport_clients);
3643
#endif
3744

38-
static const struct k_work_queue_config smp_work_queue_config = {
39-
.name = "mcumgr smp"
40-
};
4145

4246
NET_BUF_POOL_DEFINE(pkt_pool, CONFIG_MCUMGR_TRANSPORT_NETBUF_COUNT,
4347
CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE,
@@ -157,6 +161,15 @@ int smp_transport_init(struct smp_transport *smpt)
157161
k_work_init(&smpt->work, smp_handle_reqs);
158162
k_fifo_init(&smpt->fifo);
159163

164+
#ifdef CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_MODEL_DEDICATED
165+
/* Initialize dedicated work queue */
166+
k_work_queue_init(&smpt->work_queue);
167+
168+
k_work_queue_start(&smpt->work_queue, smpt->work_queue_stack,
169+
K_THREAD_STACK_SIZEOF(smpt->work_queue_stack),
170+
CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_THREAD_PRIO, &smp_work_queue_config);
171+
#endif /* CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_MODEL_DEDICATED */
172+
160173
return 0;
161174
}
162175

@@ -200,16 +213,23 @@ WEAK void
200213
smp_rx_req(struct smp_transport *smpt, struct net_buf *nb)
201214
{
202215
k_fifo_put(&smpt->fifo, nb);
203-
k_work_submit_to_queue(&smp_work_queue, &smpt->work);
216+
k_work_submit_to_queue(smp_get_wq(smpt), &smpt->work);
204217
}
205218

206-
#ifdef CONFIG_SMP_CLIENT
207-
struct k_work_q *smp_get_wq(void)
219+
struct k_work_q *smp_get_wq(struct smp_transport *smpt)
208220
{
209-
return &smp_work_queue;
210-
}
221+
struct k_work_q *work_q = NULL;
222+
#ifdef CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_MODEL_GLOBAL
223+
work_q = &smp_work_queue;
224+
#elif defined(CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_MODEL_DEDICATED)
225+
work_q = &smpt->work_queue;
226+
#else
227+
#error "No workqueue model defined"
211228
#endif
212229

230+
return work_q;
231+
}
232+
213233
void smp_rx_remove_invalid(struct smp_transport *zst, void *arg)
214234
{
215235
struct net_buf *nb;
@@ -245,7 +265,7 @@ void smp_rx_remove_invalid(struct smp_transport *zst, void *arg)
245265

246266
/* If at least one entry remains, queue the workqueue for running */
247267
if (!k_fifo_is_empty(&zst->fifo)) {
248-
k_work_submit_to_queue(&smp_work_queue, &zst->work);
268+
k_work_submit_to_queue(smp_get_wq(zst), &zst->work);
249269
}
250270
}
251271

@@ -266,11 +286,13 @@ void smp_rx_clear(struct smp_transport *zst)
266286

267287
static int smp_init(void)
268288
{
289+
#ifdef CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_MODEL_GLOBAL
269290
k_work_queue_init(&smp_work_queue);
270291

271292
k_work_queue_start(&smp_work_queue, smp_work_queue_stack,
272293
K_THREAD_STACK_SIZEOF(smp_work_queue_stack),
273294
CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_THREAD_PRIO, &smp_work_queue_config);
295+
#endif /* CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_MODEL_GLOBAL */
274296

275297
return 0;
276298
}

0 commit comments

Comments
 (0)