From a28ef1776ed35c6eb975808075aedb89e1ab146d Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Wed, 7 Sep 2016 13:07:30 +0800 Subject: [PATCH 1/4] lwip: add socket tx flow control --- components/lwip/api/sockets.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 5b109eb375..3616ce2940 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -389,18 +389,18 @@ static void lwip_socket_drop_registered_memberships(int s); #ifdef LWIP_ESP8266 extern size_t system_get_free_heap_size(void); - -#define DELAY_WHEN_MEMORY_NOT_ENOUGH() \ +extern bool esp_wifi_tx_is_stop(void); +#define ESP32_TX_FLOW_CTRL() \ do{\ uint8_t _wait_delay = 0;\ - while (system_get_free_heap_size() < HEAP_HIGHWAT){\ + while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_tx_is_stop()){\ vTaskDelay(_wait_delay/portTICK_RATE_MS);\ if (_wait_delay < 64) _wait_delay *= 2;\ }\ }while(0) #else -#define DELAY_WHEN_MEMORY_NOT_ENOUGH() +#define ESP32_TX_FLOW_CTRL() #endif /** The global array of available sockets */ @@ -1219,7 +1219,7 @@ lwip_send(int s, const void *data, size_t size, int flags) #endif /* (LWIP_UDP || LWIP_RAW) */ } - DELAY_WHEN_MEMORY_NOT_ENOUGH(); + ESP32_TX_FLOW_CTRL(); write_flags = NETCONN_COPY | ((flags & MSG_MORE) ? NETCONN_MORE : 0) | @@ -1402,7 +1402,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, #endif /* LWIP_TCP */ } - DELAY_WHEN_MEMORY_NOT_ENOUGH(); + ESP32_TX_FLOW_CTRL(); if ((to != NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) { /* sockaddr does not match socket type (IPv4/IPv6) */ From 19c8476344d30daaf81dac90420731cae53f317f Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Fri, 9 Sep 2016 10:20:14 +0800 Subject: [PATCH 2/4] modify macro ESP32_TX_FLOW_CTRL to inline function --- components/lwip/api/sockets.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 3616ce2940..4123712c15 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -390,17 +390,18 @@ static void lwip_socket_drop_registered_memberships(int s); #ifdef LWIP_ESP8266 extern size_t system_get_free_heap_size(void); extern bool esp_wifi_tx_is_stop(void); -#define ESP32_TX_FLOW_CTRL() \ -do{\ - uint8_t _wait_delay = 0;\ - while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_tx_is_stop()){\ - vTaskDelay(_wait_delay/portTICK_RATE_MS);\ - if (_wait_delay < 64) _wait_delay *= 2;\ - }\ -}while(0) +inline void esp32_tx_flow_ctrl(void) +{ + uint8_t _wait_delay = 0; + + while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_tx_is_stop()){ + vTaskDelay(_wait_delay/portTICK_RATE_MS); + if (_wait_delay < 64) _wait_delay *= 2; + } +} #else -#define ESP32_TX_FLOW_CTRL() +#define esp32_tx_flow_ctrl() #endif /** The global array of available sockets */ @@ -1219,7 +1220,7 @@ lwip_send(int s, const void *data, size_t size, int flags) #endif /* (LWIP_UDP || LWIP_RAW) */ } - ESP32_TX_FLOW_CTRL(); + esp32_tx_flow_ctrl(); write_flags = NETCONN_COPY | ((flags & MSG_MORE) ? NETCONN_MORE : 0) | @@ -1402,7 +1403,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags, #endif /* LWIP_TCP */ } - ESP32_TX_FLOW_CTRL(); + esp32_tx_flow_ctrl(); if ((to != NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) { /* sockaddr does not match socket type (IPv4/IPv6) */ From e38c4b0365b495f19cf3079f4e6d2fdf27539b7c Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Fri, 9 Sep 2016 14:31:10 +0800 Subject: [PATCH 3/4] modify esp32_tx_flow_ctrl to static function and move extern api to header file --- components/lwip/api/sockets.c | 6 +++--- components/lwip/include/lwip/port/arch/sys_arch.h | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 4123712c15..851915877d 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -388,9 +388,9 @@ static void lwip_socket_drop_registered_memberships(int s); #endif /* LWIP_IGMP */ #ifdef LWIP_ESP8266 -extern size_t system_get_free_heap_size(void); -extern bool esp_wifi_tx_is_stop(void); -inline void esp32_tx_flow_ctrl(void) +//extern size_t system_get_free_heap_size(void); +//extern bool esp_wifi_tx_is_stop(void); +static inline void esp32_tx_flow_ctrl(void) { uint8_t _wait_delay = 0; diff --git a/components/lwip/include/lwip/port/arch/sys_arch.h b/components/lwip/include/lwip/port/arch/sys_arch.h index 945b4e170a..3895f23b3b 100644 --- a/components/lwip/include/lwip/port/arch/sys_arch.h +++ b/components/lwip/include/lwip/port/arch/sys_arch.h @@ -69,6 +69,8 @@ sys_sem_t* sys_thread_sem_init(void); void sys_thread_sem_deinit(void); sys_sem_t* sys_thread_sem_get(void); - +size_t system_get_free_heap_size(void); +bool esp_wifi_tx_is_stop(void); + #endif /* __SYS_ARCH_H__ */ From 32f01c61a2d3d6226bb44f297cedf24d4427f241 Mon Sep 17 00:00:00 2001 From: liuzhifu Date: Fri, 9 Sep 2016 17:54:13 +0800 Subject: [PATCH 4/4] add comments about current tx flow control --- components/lwip/api/sockets.c | 14 ++++++++++++-- components/lwip/include/lwip/port/arch/sys_arch.h | 4 ---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/components/lwip/api/sockets.c b/components/lwip/api/sockets.c index 851915877d..91a5222e68 100755 --- a/components/lwip/api/sockets.c +++ b/components/lwip/api/sockets.c @@ -388,8 +388,18 @@ static void lwip_socket_drop_registered_memberships(int s); #endif /* LWIP_IGMP */ #ifdef LWIP_ESP8266 -//extern size_t system_get_free_heap_size(void); -//extern bool esp_wifi_tx_is_stop(void); + +/* Since esp_wifi_tx_is_stop/system_get_free_heap_size are not an public wifi API, so extern them here*/ +extern size_t system_get_free_heap_size(void); +extern bool esp_wifi_tx_is_stop(void); + +/* Please be notified that this flow control is just a workaround for fixing wifi Q full issue. + * Under UDP/TCP pressure test, we found that the sockets may cause wifi tx queue full if the socket + * sending speed is faster than the wifi sending speed, it will finally cause the packet to be dropped + * in wifi layer, it's not acceptable in some application. That's why we introdue the tx flow control here. + * However, current solution is just a workaround, we need to consider the return value of wifi tx interface, + * and feedback the return value to lwip and let lwip do the flow control itself. + */ static inline void esp32_tx_flow_ctrl(void) { uint8_t _wait_delay = 0; diff --git a/components/lwip/include/lwip/port/arch/sys_arch.h b/components/lwip/include/lwip/port/arch/sys_arch.h index 3895f23b3b..be8ff72260 100644 --- a/components/lwip/include/lwip/port/arch/sys_arch.h +++ b/components/lwip/include/lwip/port/arch/sys_arch.h @@ -68,9 +68,5 @@ void sys_delay_ms(uint32_t ms); sys_sem_t* sys_thread_sem_init(void); void sys_thread_sem_deinit(void); sys_sem_t* sys_thread_sem_get(void); - -size_t system_get_free_heap_size(void); -bool esp_wifi_tx_is_stop(void); - #endif /* __SYS_ARCH_H__ */