drivers: wifi: esp: flush socket work items in socket put

There might be some scheduled work related to socket currently requested
to be destroyed/closed. Schedule a dummy work to make sure all
previously running work items in workqueue are finished.

When talking about TX packets, this makes sure that all previously
scheduled data is actually sent (flushed) before closing socket.

Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
This commit is contained in:
Marcin Niestroj 2020-12-01 15:31:18 +01:00 committed by Carles Cufí
parent 74e4f77fb4
commit dca2fd8042
3 changed files with 30 additions and 2 deletions

View file

@ -230,6 +230,8 @@ void esp_socket_close(struct esp_socket *sock);
void esp_socket_rx(struct esp_socket *sock, struct net_buf *buf,
size_t offset, size_t len);
void esp_socket_workq_flush(struct esp_socket *sock);
static inline struct esp_data *esp_socket_to_dev(struct esp_socket *sock)
{
return CONTAINER_OF(sock - sock->idx, struct esp_data, sockets);

View file

@ -552,10 +552,10 @@ static int esp_recv(struct net_context *context,
static int esp_put(struct net_context *context)
{
struct esp_socket *sock;
struct esp_socket *sock = context->offload_context;
struct net_pkt *pkt;
sock = (struct esp_socket *)context->offload_context;
esp_socket_workq_flush(sock);
if (esp_socket_connected(sock)) {
esp_socket_close(sock);

View file

@ -14,6 +14,11 @@ LOG_MODULE_DECLARE(wifi_esp, CONFIG_WIFI_LOG_LEVEL);
#define RX_NET_PKT_ALLOC_TIMEOUT \
K_MSEC(CONFIG_WIFI_ESP_RX_NET_PKT_ALLOC_TIMEOUT)
struct esp_workq_flush_data {
struct k_work work;
struct k_sem sem;
};
/* esp_data->mtx_sock should be held */
struct esp_socket *esp_socket_get(struct esp_data *data)
{
@ -166,3 +171,24 @@ void esp_socket_close(struct esp_socket *sock)
sock->link_id, ret);
}
}
static void esp_workq_flush_work(struct k_work *work)
{
struct esp_workq_flush_data *flush =
CONTAINER_OF(work, struct esp_workq_flush_data, work);
k_sem_give(&flush->sem);
}
void esp_socket_workq_flush(struct esp_socket *sock)
{
struct esp_data *data = esp_socket_to_dev(sock);
struct esp_workq_flush_data flush;
k_work_init(&flush.work, esp_workq_flush_work);
k_sem_init(&flush.sem, 0, 1);
k_work_submit_to_queue(&data->workq, &flush.work);
k_sem_take(&flush.sem, K_FOREVER);
}