Skip to content

Commit 9fa82f0

Browse files
SeppoTakalokartben
authored andcommitted
mgmt: smp: Fix race condition by using same work queue
Fix possible race condition where SMP client might release the network buffer before system worker queue has processed it. In smp_client uses shared resources like worker queue linked list and network buffers without maintaining any thread safety. For unknown reasons, retry timeout handling is pushed into system worker queue while the actual transmission is handled from SMP work queue. Fix the issue by using the same SMP work queue for both delayable timeout handling as well as transmission handling. Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
1 parent 3163325 commit 9fa82f0

File tree

3 files changed

+11
-9
lines changed

3 files changed

+11
-9
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
smp_tx_req(&entry->smp_client->work);
115+
k_work_submit_to_queue(smp_get_wq(), &entry->smp_client->work);
116116
continue;
117117
}
118118

@@ -126,7 +126,8 @@ 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(&smp_client_data.work_delay, K_MSEC(backoff_ms));
129+
k_work_reschedule_for_queue(smp_get_wq(), &smp_client_data.work_delay,
130+
K_MSEC(backoff_ms));
130131
}
131132
}
132133

@@ -160,7 +161,8 @@ static void smp_cmd_add_to_list(struct smp_client_cmd_req *cmd_req)
160161
{
161162
if (sys_slist_is_empty(&smp_client_data.cmd_list)) {
162163
/* Enable timer */
163-
k_work_reschedule(&smp_client_data.work_delay, K_MSEC(CONFIG_SMP_CMD_RETRY_TIME));
164+
k_work_reschedule_for_queue(smp_get_wq(), &smp_client_data.work_delay,
165+
K_MSEC(CONFIG_SMP_CMD_RETRY_TIME));
164166
}
165167
sys_slist_append(&smp_client_data.cmd_list, &cmd_req->node);
166168
}
@@ -320,7 +322,7 @@ int smp_client_send_cmd(struct smp_client_object *smp_client, struct net_buf *nb
320322
nb = net_buf_ref(nb);
321323
smp_cmd_add_to_list(cmd_req);
322324
k_fifo_put(&smp_client->tx_fifo, nb);
323-
smp_tx_req(&smp_client->work);
325+
k_work_submit_to_queue(smp_get_wq(), &smp_client->work);
324326
return MGMT_ERR_EOK;
325327
}
326328

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ void smp_rx_req(struct smp_transport *smtp, struct net_buf *nb);
5050

5151
#ifdef CONFIG_SMP_CLIENT
5252
/**
53-
* @brief Trig SMP client request packet for transmission.
53+
* @brief Get work queue for SMP client.
5454
*
55-
* @param work The transport to use to send the corresponding response(s).
55+
* @return SMP work queue object.
5656
*/
57-
void smp_tx_req(struct k_work *work);
57+
struct k_work_q *smp_get_wq(void);
5858
#endif
5959

6060
/**

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ smp_rx_req(struct smp_transport *smpt, struct net_buf *nb)
204204
}
205205

206206
#ifdef CONFIG_SMP_CLIENT
207-
void smp_tx_req(struct k_work *work)
207+
struct k_work_q *smp_get_wq(void)
208208
{
209-
k_work_submit_to_queue(&smp_work_queue, work);
209+
return &smp_work_queue;
210210
}
211211
#endif
212212

0 commit comments

Comments
 (0)