From e4c602747bc20acfacbab3432fc3961c38cf7356 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 2 Feb 2015 14:48:11 -0600 Subject: [PATCH] Networking: Fixes another CONFIG_NET_NOINTS issues. When called sem_timedwait() with the network locked, the network stays logcked while we wait which is not what we want (without CONFIG_NET_NOINTS, interrupts are re-enabled while we wait and all is well). --- net/arp/arp.h | 6 +++--- net/arp/arp_notify.c | 6 +++--- net/arp/arp_send.c | 12 ++++++++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/net/arp/arp.h b/net/arp/arp.h index e6047cd337..1b0e6d8fa7 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -345,8 +345,8 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify); * timeout occurs. * * Assumptions: - * This function is called from ARP send and executes in the normal - * tasking environment. + * This function is called from ARP send and mut execute with the network + * un-locked. * ****************************************************************************/ @@ -366,7 +366,7 @@ int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout); * * Assumptions: * This function is called from the MAC device driver indirectly through - * arp_arpin() and may be execute from the interrupt level. + * arp_arpin() and will execute with the network locked. * ****************************************************************************/ diff --git a/net/arp/arp_notify.c b/net/arp/arp_notify.c index 40ca91f0a7..19e082f221 100644 --- a/net/arp/arp_notify.c +++ b/net/arp/arp_notify.c @@ -166,8 +166,8 @@ int arp_wait_cancel(FAR struct arp_notify_s *notify) * timeout occurs. * * Assumptions: - * This function is called from ARP send and executes in the normal - * tasking environment. + * This function is called from ARP send must execute with the network + * un-locked (interrupts may be disabled to keep the things stable). * ****************************************************************************/ @@ -220,7 +220,7 @@ int arp_wait(FAR struct arp_notify_s *notify, FAR struct timespec *timeout) * * Assumptions: * This function is called from the MAC device driver indirectly through - * arp_arpin() and may be execute from the interrupt level. + * arp_arpin() will execute with the network locked. * ****************************************************************************/ diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index 42421a9dea..97485d8c70 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -190,6 +190,9 @@ int arp_send(in_addr_t ipaddr) struct arp_notify_s notify; struct timespec delay; struct arp_send_s state; +#ifdef CONFIG_NET_NOINTS + irqstate_t flags; +#endif net_lock_t save; int ret; @@ -358,12 +361,21 @@ int arp_send(in_addr_t ipaddr) /* Now wait for response to the ARP response to be received. The * optimal delay would be the work case round trip time. + * NOTE: The network is locked. */ delay.tv_sec = CONFIG_ARP_SEND_DELAYSEC; delay.tv_nsec = CONFIG_ARP_SEND_DELAYNSEC; +#ifdef CONFIG_NET_NOINTS + flags = irqsave(); /* Keep things stable */ + net_unlock(save); /* Unlock the network with interrupts disabled */ +#endif ret = arp_wait(¬ify, &delay); +#ifdef CONFIG_NET_NOINTS + save = net_lock(); /* Re-lock the network with interrupts disabled */ + irqrestore(flags); +#endif /* arp_wait will return OK if and only if the matching ARP response * is received. Otherwise, it will return -ETIMEDOUT.