Skip to content

Commit

Permalink
mgmt: smp: Fix race condition by using same work queue
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
SeppoTakalo authored and kartben committed Dec 6, 2024
1 parent 3163325 commit 9fa82f0
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 9 deletions.
10 changes: 6 additions & 4 deletions subsys/mgmt/mcumgr/smp_client/src/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ static void smp_client_transport_work_fn(struct k_work *work)
entry->retry_cnt--;
entry->timestamp = time_stamp_ref + CONFIG_SMP_CMD_RETRY_TIME;
k_fifo_put(&entry->smp_client->tx_fifo, entry->nb);
smp_tx_req(&entry->smp_client->work);
k_work_submit_to_queue(smp_get_wq(), &entry->smp_client->work);
continue;
}

Expand All @@ -126,7 +126,8 @@ static void smp_client_transport_work_fn(struct k_work *work)

if (!sys_slist_is_empty(&smp_client_data.cmd_list)) {
/* Re-schedule new timeout to next */
k_work_reschedule(&smp_client_data.work_delay, K_MSEC(backoff_ms));
k_work_reschedule_for_queue(smp_get_wq(), &smp_client_data.work_delay,
K_MSEC(backoff_ms));
}
}

Expand Down Expand Up @@ -160,7 +161,8 @@ static void smp_cmd_add_to_list(struct smp_client_cmd_req *cmd_req)
{
if (sys_slist_is_empty(&smp_client_data.cmd_list)) {
/* Enable timer */
k_work_reschedule(&smp_client_data.work_delay, K_MSEC(CONFIG_SMP_CMD_RETRY_TIME));
k_work_reschedule_for_queue(smp_get_wq(), &smp_client_data.work_delay,
K_MSEC(CONFIG_SMP_CMD_RETRY_TIME));
}
sys_slist_append(&smp_client_data.cmd_list, &cmd_req->node);
}
Expand Down Expand Up @@ -320,7 +322,7 @@ int smp_client_send_cmd(struct smp_client_object *smp_client, struct net_buf *nb
nb = net_buf_ref(nb);
smp_cmd_add_to_list(cmd_req);
k_fifo_put(&smp_client->tx_fifo, nb);
smp_tx_req(&smp_client->work);
k_work_submit_to_queue(smp_get_wq(), &smp_client->work);
return MGMT_ERR_EOK;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ void smp_rx_req(struct smp_transport *smtp, struct net_buf *nb);

#ifdef CONFIG_SMP_CLIENT
/**
* @brief Trig SMP client request packet for transmission.
* @brief Get work queue for SMP client.
*
* @param work The transport to use to send the corresponding response(s).
* @return SMP work queue object.
*/
void smp_tx_req(struct k_work *work);
struct k_work_q *smp_get_wq(void);
#endif

/**
Expand Down
4 changes: 2 additions & 2 deletions subsys/mgmt/mcumgr/transport/src/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,9 @@ smp_rx_req(struct smp_transport *smpt, struct net_buf *nb)
}

#ifdef CONFIG_SMP_CLIENT
void smp_tx_req(struct k_work *work)
struct k_work_q *smp_get_wq(void)
{
k_work_submit_to_queue(&smp_work_queue, work);
return &smp_work_queue;
}
#endif

Expand Down

0 comments on commit 9fa82f0

Please sign in to comment.