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.
This commit is contained in:
Alexander Lunev 2022-01-27 14:45:32 +03:00 committed by Xiang Xiao
parent e596d5bd5e
commit b2f3cefe3d
6 changed files with 87 additions and 39 deletions

View File

@ -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 ***********************************************************/

View File

@ -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 */

View File

@ -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)

View File

@ -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();
}

View File

@ -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));

View File

@ -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;