net: add poll lock for local socket poll

net_lock/unlock is a big lock and repleace it to internal pool lock
to avoid the priority inversion problem.

Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
This commit is contained in:
zhangyuan21
2023-07-27 18:34:23 +08:00
committed by Alin Jerpelea
parent 904266ab23
commit 114d641f4a
3 changed files with 21 additions and 15 deletions
+1
View File
@@ -132,6 +132,7 @@ struct local_conn_s
#endif /* CONFIG_NET_LOCAL_SCM */ #endif /* CONFIG_NET_LOCAL_SCM */
mutex_t lc_sendlock; /* Make sending multi-thread safe */ mutex_t lc_sendlock; /* Make sending multi-thread safe */
mutex_t lc_polllock; /* Lock for net poll */
#ifdef CONFIG_NET_LOCAL_STREAM #ifdef CONFIG_NET_LOCAL_STREAM
/* SOCK_STREAM fields common to both client and server */ /* SOCK_STREAM fields common to both client and server */
+2
View File
@@ -129,6 +129,7 @@ FAR struct local_conn_s *local_alloc(void)
*/ */
nxmutex_init(&conn->lc_sendlock); nxmutex_init(&conn->lc_sendlock);
nxmutex_init(&conn->lc_polllock);
#ifdef CONFIG_NET_LOCAL_SCM #ifdef CONFIG_NET_LOCAL_SCM
conn->lc_cred.pid = nxsched_getpid(); conn->lc_cred.pid = nxsched_getpid();
@@ -217,6 +218,7 @@ void local_free(FAR struct local_conn_s *conn)
/* Destory sem associated with the connection */ /* Destory sem associated with the connection */
nxmutex_destroy(&conn->lc_sendlock); nxmutex_destroy(&conn->lc_sendlock);
nxmutex_destroy(&conn->lc_polllock);
/* And free the connection structure */ /* And free the connection structure */
+16 -13
View File
@@ -50,13 +50,14 @@ static int local_event_pollsetup(FAR struct local_conn_s *conn,
int ret = OK; int ret = OK;
int i; int i;
net_lock();
if (setup) if (setup)
{ {
/* This is a request to set up the poll. Find an available /* This is a request to set up the poll. Find an available
* slot for the poll structure reference * slot for the poll structure reference
*/ */
nxmutex_lock(&conn->lc_polllock);
for (i = 0; i < LOCAL_NPOLLWAITERS; i++) for (i = 0; i < LOCAL_NPOLLWAITERS; i++)
{ {
/* Find an available slot */ /* Find an available slot */
@@ -71,11 +72,12 @@ static int local_event_pollsetup(FAR struct local_conn_s *conn,
} }
} }
nxmutex_unlock(&conn->lc_polllock);
if (i >= LOCAL_NPOLLWAITERS) if (i >= LOCAL_NPOLLWAITERS)
{ {
fds->priv = NULL; fds->priv = NULL;
ret = -EBUSY; return -EBUSY;
goto errout;
} }
eventset = 0; eventset = 0;
@@ -93,20 +95,19 @@ static int local_event_pollsetup(FAR struct local_conn_s *conn,
struct pollfd **slot = (struct pollfd **)fds->priv; struct pollfd **slot = (struct pollfd **)fds->priv;
if (!slot) nxmutex_lock(&conn->lc_polllock);
{
ret = -EIO;
goto errout;
}
/* Remove all memory of the poll setup */ /* Remove all memory of the poll setup */
if (slot != NULL)
{
*slot = NULL; *slot = NULL;
fds->priv = NULL; fds->priv = NULL;
} }
errout: nxmutex_unlock(&conn->lc_polllock);
net_unlock(); }
return ret; return ret;
} }
@@ -135,7 +136,9 @@ void local_event_pollnotify(FAR struct local_conn_s *conn,
pollevent_t eventset) pollevent_t eventset)
{ {
#ifdef CONFIG_NET_LOCAL_STREAM #ifdef CONFIG_NET_LOCAL_STREAM
nxmutex_lock(&conn->lc_polllock);
poll_notify(conn->lc_event_fds, LOCAL_NPOLLWAITERS, eventset); poll_notify(conn->lc_event_fds, LOCAL_NPOLLWAITERS, eventset);
nxmutex_unlock(&conn->lc_polllock);
#endif #endif
} }
@@ -197,7 +200,7 @@ int local_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
/* Find shadow pollfds. */ /* Find shadow pollfds. */
net_lock(); nxmutex_lock(&conn->lc_polllock);
shadowfds = conn->lc_inout_fds; shadowfds = conn->lc_inout_fds;
while (shadowfds->fd != 0) while (shadowfds->fd != 0)
@@ -205,7 +208,7 @@ int local_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
shadowfds += 2; shadowfds += 2;
if (shadowfds >= &conn->lc_inout_fds[2*LOCAL_NPOLLWAITERS]) if (shadowfds >= &conn->lc_inout_fds[2*LOCAL_NPOLLWAITERS])
{ {
net_unlock(); nxmutex_unlock(&conn->lc_polllock);
return -ENOMEM; return -ENOMEM;
} }
} }
@@ -222,7 +225,7 @@ int local_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
shadowfds[1].arg = fds; shadowfds[1].arg = fds;
shadowfds[1].events &= ~POLLIN; shadowfds[1].events &= ~POLLIN;
net_unlock(); nxmutex_unlock(&conn->lc_polllock);
/* Setup poll for both shadow pollfds. */ /* Setup poll for both shadow pollfds. */