From b2f3cefe3d3b873e8f04bbf18b07254e0a98fce0 Mon Sep 17 00:00:00 2001 From: Alexander Lunev Date: Thu, 27 Jan 2022 14:45:32 +0300 Subject: [PATCH] sim/netdev,tapdev: implemented emulation of TX done and RX ready interrupts and removed two tcp_send_txnotify() calls from tcp_sendfile (they are not needed anymore). As a result, the TX throughput of both the tcp_send_buffered and tcp_send_unbuffered is significantly boosted in case of TUN/TAP network device. --- arch/sim/src/sim/up_internal.h | 48 ++++++++++++++++++--------------- arch/sim/src/sim/up_netdriver.c | 28 ++++++++++++++----- arch/sim/src/sim/up_tapdev.c | 30 ++++++++++++++++++++- arch/sim/src/sim/up_vpnkit.c | 6 ++++- arch/sim/src/sim/up_wpcap.c | 6 ++++- net/tcp/tcp_sendfile.c | 8 ------ 6 files changed, 87 insertions(+), 39 deletions(-) diff --git a/arch/sim/src/sim/up_internal.h b/arch/sim/src/sim/up_internal.h index 3d4db6248d..bfdb8cc37c 100644 --- a/arch/sim/src/sim/up_internal.h +++ b/arch/sim/src/sim/up_internal.h @@ -247,52 +247,58 @@ int sim_ajoy_initialize(void); /* up_tapdev.c **************************************************************/ #if defined(CONFIG_SIM_NETDEV_TAP) && !defined(__CYGWIN__) -void tapdev_init(void); +void tapdev_init(void *priv, + void (*tx_done_intr_cb)(void *priv), + void (*rx_ready_intr_cb)(void *priv)); int tapdev_avail(void); unsigned int tapdev_read(unsigned char *buf, unsigned int buflen); void tapdev_send(unsigned char *buf, unsigned int buflen); void tapdev_ifup(in_addr_t ifaddr); void tapdev_ifdown(void); -# define netdev_init() tapdev_init() -# define netdev_avail() tapdev_avail() -# define netdev_read(buf,buflen) tapdev_read(buf,buflen) -# define netdev_send(buf,buflen) tapdev_send(buf,buflen) -# define netdev_ifup(ifaddr) tapdev_ifup(ifaddr) -# define netdev_ifdown() tapdev_ifdown() +# define netdev_init(priv,txcb,rxcb) tapdev_init(priv,txcb,rxcb) +# define netdev_avail() tapdev_avail() +# define netdev_read(buf,buflen) tapdev_read(buf,buflen) +# define netdev_send(buf,buflen) tapdev_send(buf,buflen) +# define netdev_ifup(ifaddr) tapdev_ifup(ifaddr) +# define netdev_ifdown() tapdev_ifdown() #endif /* up_wpcap.c ***************************************************************/ #if defined(CONFIG_SIM_NETDEV_TAP) && defined(__CYGWIN__) -void wpcap_init(void); +void wpcap_init(void *priv, + void (*tx_done_intr_cb)(void *priv), + void (*rx_ready_intr_cb)(void *priv)); unsigned int wpcap_read(unsigned char *buf, unsigned int buflen); void wpcap_send(unsigned char *buf, unsigned int buflen); -# define netdev_init() wpcap_init() -# define netdev_avail() 1 -# define netdev_read(buf,buflen) wpcap_read(buf,buflen) -# define netdev_send(buf,buflen) wpcap_send(buf,buflen) -# define netdev_ifup(ifaddr) {} -# define netdev_ifdown() {} +# define netdev_init(priv,txcb,rxcb) wpcap_init(priv,txcb,rxcb) +# define netdev_avail() 1 +# define netdev_read(buf,buflen) wpcap_read(buf,buflen) +# define netdev_send(buf,buflen) wpcap_send(buf,buflen) +# define netdev_ifup(ifaddr) {} +# define netdev_ifdown() {} #endif /* up_vpnkit.c **************************************************************/ #if defined(CONFIG_SIM_NETDEV_VPNKIT) -void vpnkit_init(void); +void vpnkit_init(void *priv, + void (*tx_done_intr_cb)(void *priv), + void (*rx_ready_intr_cb)(void *priv)); int vpnkit_avail(void); unsigned int vpnkit_read(unsigned char *buf, unsigned int buflen); void vpnkit_send(unsigned char *buf, unsigned int buflen); void vpnkit_ifup(in_addr_t ifaddr); void vpnkit_ifdown(void); -# define netdev_init() vpnkit_init() -# define netdev_avail() vpnkit_avail() -# define netdev_read(buf,buflen) vpnkit_read(buf,buflen) -# define netdev_send(buf,buflen) vpnkit_send(buf,buflen) -# define netdev_ifup(ifaddr) vpnkit_ifup(ifaddr) -# define netdev_ifdown() vpnkit_ifdown() +# define netdev_init(priv,txcb,rxcb) vpnkit_init(priv,txcb,rxcb) +# define netdev_avail() vpnkit_avail() +# define netdev_read(buf,buflen) vpnkit_read(buf,buflen) +# define netdev_send(buf,buflen) vpnkit_send(buf,buflen) +# define netdev_ifup(ifaddr) vpnkit_ifup(ifaddr) +# define netdev_ifdown() vpnkit_ifdown() #endif /* up_netdriver.c ***********************************************************/ diff --git a/arch/sim/src/sim/up_netdriver.c b/arch/sim/src/sim/up_netdriver.c index 592c0a6f71..310c91b707 100644 --- a/arch/sim/src/sim/up_netdriver.c +++ b/arch/sim/src/sim/up_netdriver.c @@ -323,15 +323,27 @@ static int netdriver_txavail(FAR struct net_driver_s *dev) work_queue(LPWORK, &g_avail_work, netdriver_txavail_work, dev, 0); } - /* Check RX data availability and read the data from the network device now - * to prevent RX data stream congestion in case of high TX network traffic. - */ - - netdriver_loop(); - return OK; } +static void netdriver_txdone_interrupt(FAR void *priv) +{ + if (work_available(&g_avail_work)) + { + FAR struct net_driver_s *dev = (FAR struct net_driver_s *)priv; + work_queue(LPWORK, &g_avail_work, netdriver_txavail_work, dev, 0); + } +} + +static void netdriver_rxready_interrupt(FAR void *priv) +{ + if (work_available(&g_recv_work)) + { + FAR struct net_driver_s *dev = (FAR struct net_driver_s *)priv; + work_queue(LPWORK, &g_recv_work, netdriver_recv_work, dev, 0); + } +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -344,7 +356,9 @@ int netdriver_init(void) /* Internal initialization */ - netdev_init(); + netdev_init(dev, + netdriver_txdone_interrupt, + netdriver_rxready_interrupt); /* Update the buffer size */ diff --git a/arch/sim/src/sim/up_tapdev.c b/arch/sim/src/sim/up_tapdev.c index 7f67aaddb8..13ecc1b545 100644 --- a/arch/sim/src/sim/up_tapdev.c +++ b/arch/sim/src/sim/up_tapdev.c @@ -95,6 +95,9 @@ static int gdrop = 0; #endif static int gtapdevfd = -1; static char gdevname[IFNAMSIZ]; +static void *g_priv = NULL; +static void (*g_tx_done_intr_cb)(void *priv) = NULL; +static void (*g_rx_ready_intr_cb)(void *priv) = NULL; #ifdef CONFIG_SIM_NET_HOST_ROUTE static struct rtentry ghostroute; @@ -157,7 +160,9 @@ static void set_macaddr(void) * Public Functions ****************************************************************************/ -void tapdev_init(void) +void tapdev_init(void *priv, + void (*tx_done_intr_cb)(void *priv), + void (*rx_ready_intr_cb)(void *priv)) { struct ifreq ifr; int tapdevfd; @@ -238,6 +243,15 @@ void tapdev_init(void) #endif gtapdevfd = tapdevfd; + g_priv = priv; + + /* Register the emulated TX done interrupt callback */ + + g_tx_done_intr_cb = tx_done_intr_cb; + + /* Register the emulated RX ready interrupt callback */ + + g_rx_ready_intr_cb = rx_ready_intr_cb; /* Set the MAC address */ @@ -315,6 +329,20 @@ void tapdev_send(unsigned char *buf, unsigned int buflen) } dump_ethhdr("write", buf, buflen); + + /* Emulate TX done interrupt */ + + if (g_tx_done_intr_cb != NULL) + { + g_tx_done_intr_cb(g_priv); + } + + /* Emulate RX ready interrupt */ + + if (g_rx_ready_intr_cb != NULL && tapdev_avail()) + { + g_rx_ready_intr_cb(g_priv); + } } void tapdev_ifup(in_addr_t ifaddr) diff --git a/arch/sim/src/sim/up_vpnkit.c b/arch/sim/src/sim/up_vpnkit.c index d8782ba37e..e144be376c 100644 --- a/arch/sim/src/sim/up_vpnkit.c +++ b/arch/sim/src/sim/up_vpnkit.c @@ -131,8 +131,12 @@ static void vpnkit_disconnect(void) * ****************************************************************************/ -void vpnkit_init(void) +void vpnkit_init(void *priv, + void (*tx_done_intr_cb)(void *priv), + void (*rx_ready_intr_cb)(void *priv)) { + /* TODO: support emulation of TX done and RX ready interrupts */ + vpnkit_connect(); } diff --git a/arch/sim/src/sim/up_wpcap.c b/arch/sim/src/sim/up_wpcap.c index 0a195f3476..f988ed6daf 100644 --- a/arch/sim/src/sim/up_wpcap.c +++ b/arch/sim/src/sim/up_wpcap.c @@ -256,11 +256,15 @@ static void set_ethaddr(struct in_addr addr) * Public Functions ****************************************************************************/ -void wpcap_init(void) +void wpcap_init(void *priv, + void (*tx_done_intr_cb)(void *priv), + void (*rx_ready_intr_cb)(void *priv)) { struct in_addr addr; FARPROC dlladdr; + /* TODO: support emulation of TX done and RX ready interrupts */ + addr.s_addr = HTONL(WCAP_IPADDR); syslog(LOG_INFO, "wpcap_init: IP address: %s\n", inet_ntoa(addr)); diff --git a/net/tcp/tcp_sendfile.c b/net/tcp/tcp_sendfile.c index 1c1a1095fe..c8f1bcf176 100644 --- a/net/tcp/tcp_sendfile.c +++ b/net/tcp/tcp_sendfile.c @@ -310,10 +310,6 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev, dev->d_sndlen = sndlen; - /* Notify the device driver of the availability of TX data */ - - tcp_send_txnotify(psock, conn); - /* Continue waiting */ return flags; @@ -392,10 +388,6 @@ static uint16_t sendfile_eventhandler(FAR struct net_driver_s *dev, dev->d_sndlen = sndlen; - /* Notify the device driver of the availability of TX data */ - - tcp_send_txnotify(psock, conn); - /* Update the amount of data sent (but not necessarily ACKed) */ pstate->snd_sent += sndlen;