dns: Reduce the dns_lock granularity

When a7 curl calls dns_query via usrsock, it will wait a usrsock
response with the dns lock held. If a7 rptun recv a dns_addnameserver
event from another core at this time, rptun waits the lock held by
curl in callback. Then curl will never get its usrsock response with
rptun blocked, so the deadlock occurs.

This change will break lock when do usrsock request.

Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
This commit is contained in:
zhanghongyu 2022-11-08 21:45:20 +08:00 committed by Xiang Xiao
parent 8aa5145273
commit db4840564d
3 changed files with 56 additions and 1 deletions

View File

@ -151,6 +151,26 @@ void dns_lock(void);
void dns_unlock(void);
/****************************************************************************
* Name: dns_breaklock
*
* Description:
* Break the DNS lock
*
****************************************************************************/
void dns_breaklock(FAR unsigned int *count);
/****************************************************************************
* Name: dns_restorelock
*
* Description:
* Restore the DNS lock
*
****************************************************************************/
void dns_restorelock(unsigned int count);
/****************************************************************************
* Name: dns_bind
*

View File

@ -80,6 +80,7 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg)
char line[DNS_MAX_LINE];
FAR char *addrstr;
FAR char *ptr;
unsigned int count;
uint16_t port;
int keylen;
int ret;
@ -186,8 +187,10 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg)
{
u.ipv4.sin_family = AF_INET;
u.ipv4.sin_port = port;
dns_breaklock(&count);
ret = callback(arg, (FAR struct sockaddr *)&u.ipv4,
sizeof(struct sockaddr_in));
dns_restorelock(count);
}
else
#endif
@ -205,8 +208,10 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg)
{
u.ipv6.sin6_family = AF_INET6;
u.ipv6.sin6_port = port;
dns_breaklock(&count);
ret = callback(arg, (FAR struct sockaddr *)&u.ipv6,
sizeof(struct sockaddr_in6));
dns_restorelock(count);
}
else
#endif
@ -235,6 +240,7 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg)
int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg)
{
FAR struct sockaddr *addr;
unsigned int count;
int ret = OK;
int i;
@ -255,7 +261,9 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg)
/* Perform the callback */
dns_breaklock(&count);
ret = callback(arg, addr, sizeof(struct sockaddr_in));
dns_restorelock(count);
}
else
#endif
@ -274,7 +282,9 @@ int dns_foreach_nameserver(dns_callback_t callback, FAR void *arg)
/* Perform the callback */
dns_breaklock(&count);
ret = callback(arg, addr, sizeof(struct sockaddr_in6));
dns_restorelock(count);
}
else
#endif

View File

@ -43,7 +43,7 @@
static rmutex_t g_dns_lock = NXRMUTEX_INITIALIZER;
/****************************************************************************
* Private Functions
* Public Functions
****************************************************************************/
/****************************************************************************
@ -71,3 +71,28 @@ void dns_unlock(void)
{
nxrmutex_unlock(&g_dns_lock);
}
/****************************************************************************
* Name: dns_breaklock
*
* Description:
* Break the DNS lock
****************************************************************************/
void dns_breaklock(FAR unsigned int *count)
{
nxrmutex_breaklock(&g_dns_lock, count);
}
/****************************************************************************
* Name: dns_restorelock
*
* Description:
* Restore the DNS lock
*
****************************************************************************/
void dns_restorelock(unsigned int count)
{
nxrmutex_restorelock(&g_dns_lock, count);
}