drivers: wifi: esp: add thread-safety on esp_socket operations
Change type of esp_socket->flags from uint8_t to atomic_t, so that read
and write access to those flags is done in atomic (thread-safe) manner.
Introduce esp_socket_ref() and esp_socket_unref() functions, which
operate on atomic refcount variable. esp_socket_ref() role is to
increase refcount if it was already non-zero. If it was zero then NULL
is returned, which means that socket is not used by net_context at the
moment.
Role of refcount:
* socket instance is assured to be between net_offload->get() and
net_offload->put() when refcount > 0,
* makes sure that socket instance can be used (its members can be
dereferenced) when refcount > 0,
* 'context' member is always valid and its members can be dereferenced
when refcount > 0.
esp_socket_get() gets unused socket, as previously. Additionally it sets
refcount to 1 at the end of call, which basically means that from that
point such socket can be referenced by other parts of the driver. Each
esp_socket_get() call should be followed by esp_socket_unref() and
esp_socket_put() to properly invalidate socket and prevent other parts
of driver from using it.
Add ESP_SOCK_WORKQ_STOPPED flag, which is now used to prevent scheduling
more work into driver workqueue. This flag is set in net_offload->put()
callback, so that no more socket work (such as processing RX/TX packets
or closing socket because of errors) is submitted after that.
Introduce mutex lock, which has following role:
* protects dst, connect_cb + conn_user_data, recv_cb + recv_user_data,
* assures that checking ESP_SOCK_WORKQ_STOPPED flag and actually
submitting (or not if net_offload->put was already called) new socket
work to workqueue is done in atomic way.
As there is a mechanism to prevent submitting new work items to
workqueue when net_offload->put() has been executed, then there is no
need to explicitly call esp_socket_ref() in esp_workq thread. This is
because one reference is being held by net_context (after calling
net_context->get()). This is why all the esp_socket_in_use() were simply
dropped. Code running from esp_rx thread on the other hand always uses
esp_socket_ref_from_link_id() helper function (which is backed by
esp_socket_ref()), so that it replaces previous esp_socket_in_use()
calls and additionally makes sure that socket stays valid ("in use")
until esp_socket_unref() is called.
Signed-off-by:
Marcin Niestroj <m.niestroj@grinn-global.com>
Loading
Please sign in to comment