This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 61563d6004 risc-v/es32c3: improve passthrough performance by iob 
offload
61563d6004 is described below

commit 61563d6004fe92ae50d567bc4f81c81f60d8c757
Author: chao an <anc...@xiaomi.com>
AuthorDate: Thu Dec 8 04:03:01 2022 +0800

    risc-v/es32c3: improve passthrough performance by iob offload
    
    Use iob offload model to improve passthrough performance
    
    1. Use iob buffer instead of reserved packet buffer
    2. Enable TCP/UDP buffer mode
    
    -------------------------------------------------
    |  Protocol      | Server | Client |            |
    |-----------------------------------------------|
    |  TCP           |    7   |    12  |  Mbits/sec |
    |  TCP(Offload)  |   17   |    11  |  Mbits/sec |
    |  UDP           |   10   |    16  |  Mbits/sec |
    |  UDP(Offload)  |   43   |    28  |  Mbits/sec |
    -------------------------------------------------
    
    Signed-off-by: chao an <anc...@xiaomi.com>
---
 arch/risc-v/src/esp32c3/Kconfig                    |   4 -
 arch/risc-v/src/esp32c3/esp32c3_wlan.c             | 434 ++++-----------------
 .../esp32c3/esp32c3-devkit/configs/wapi/defconfig  |   7 +-
 3 files changed, 83 insertions(+), 362 deletions(-)

diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig
index 2e50ab919e..5251916dba 100644
--- a/arch/risc-v/src/esp32c3/Kconfig
+++ b/arch/risc-v/src/esp32c3/Kconfig
@@ -755,10 +755,6 @@ config ESP32C3_WIFI_RXBA_AMPDU_WZ
        int "Wi-Fi RX BA AMPDU windown size"
        default 6
 
-config ESP32C3_WLAN_PKTBUF_NUM
-       int "WLAN netcard packet buffer number per netcard"
-       default 16
-
 config ESP32C3_WIFI_CONNECT_TIMEOUT
        int "Connect timeout by second"
        default 10
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wlan.c 
b/arch/risc-v/src/esp32c3/esp32c3_wlan.c
index 7da216ca45..7161e16cf3 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_wlan.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_wlan.c
@@ -72,41 +72,14 @@
  *     Total size         :   1514
  */
 
-#define WLAN_BUF_SIZE             (CONFIG_NET_ETH_PKTSIZE)
-
-/* WLAN packet buffer number */
-
-#define WLAN_PKTBUF_NUM           (CONFIG_ESP32C3_WLAN_PKTBUF_NUM)
-
-/* Receive threshold which allows the receive function to trigger a scheduler
- * to activate the application if possible.
- */
-
-#ifdef CONFIG_MM_IOB
-#  define IOBBUF_SIZE             (CONFIG_IOB_NBUFFERS * CONFIG_IOB_BUFSIZE)
-#  if (WLAN_PKTBUF_NUM) > (CONFIG_IOB_BUFSIZE + 1)
-#    define WLAN_RX_THRESHOLD     (IOBBUF_SIZE - WLAN_BUF_SIZE + 1)
-#   else
-#    define WLAN_RX_THRESHOLD     (WLAN_PKTBUF_NUM - 1) * WLAN_BUF_SIZE
-#  endif
-#endif
+#define WLAN_BUF_SIZE             (CONFIG_NET_ETH_PKTSIZE + \
+                                   CONFIG_NET_LL_GUARDSIZE + \
+                                   CONFIG_NET_GUARDSIZE)
 
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
-/* WLAN packet buffer */
-
-struct wlan_pktbuf_s
-{
-  sq_entry_t    entry;          /* Queue entry */
-
-  /* Packet data buffer */
-
-  uint8_t       buffer[WLAN_BUF_SIZE];
-  uint16_t      len;            /* Packet data length */
-};
-
 /* WLAN operations */
 
 struct wlan_ops_s
@@ -153,21 +126,17 @@ struct wlan_priv_s
 
   struct net_driver_s dev;
 
-  /* Packet buffer cache */
-
-  struct wlan_pktbuf_s  pktbuf[WLAN_PKTBUF_NUM];
-
   /* RX packet queue */
 
-  sq_queue_t    rxb;
+  struct iob_queue_s rxb;
 
   /* TX ready packet queue */
 
-  sq_queue_t    txb;
+  struct iob_queue_s txb;
 
-  /* Free packet buffer queue */
+  /* Flat buffer swap */
 
-  sq_queue_t    freeb;
+  uint8_t flatbuf[WLAN_BUF_SIZE];
 };
 
 /****************************************************************************
@@ -281,105 +250,6 @@ static void wlan_ipv6multicast(struct wlan_priv_s *priv);
  *     mutex/semaphore instead of disable interrupt, if necessary.
  */
 
-/****************************************************************************
- * Function: wlan_init_buffer
- *
- * Description:
- *   Initialize the free buffer list
- *
- * Input Parameters:
- *   priv - Reference to the driver state structure
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-static inline void wlan_init_buffer(struct wlan_priv_s *priv)
-{
-  int i;
-  irqstate_t flags;
-
-  flags = enter_critical_section();
-
-  priv->dev.d_buf = NULL;
-  priv->dev.d_len = 0;
-
-  sq_init(&priv->freeb);
-  sq_init(&priv->rxb);
-  sq_init(&priv->txb);
-
-  for (i = 0; i < WLAN_PKTBUF_NUM; i++)
-    {
-      sq_addlast(&priv->pktbuf[i].entry, &priv->freeb);
-    }
-
-  leave_critical_section(flags);
-}
-
-/****************************************************************************
- * Function: wlan_alloc_buffer
- *
- * Description:
- *   Allocate one buffer from the free buffer queue
- *
- * Input Parameters:
- *   priv - Reference to the driver state structure
- *
- * Returned Value:
- *   Pointer to the allocated buffer on success; NULL on failure
- *
- ****************************************************************************/
-
-static struct wlan_pktbuf_s *wlan_alloc_buffer(
-                                         struct wlan_priv_s *priv)
-{
-  sq_entry_t *entry;
-  irqstate_t flags;
-  struct wlan_pktbuf_s *pktbuf = NULL;
-
-  flags = enter_critical_section();
-
-  entry = sq_remfirst(&priv->freeb);
-  if (entry != NULL)
-    {
-      pktbuf = container_of(entry, struct wlan_pktbuf_s, entry);
-    }
-
-  leave_critical_section(flags);
-
-  return pktbuf;
-}
-
-/****************************************************************************
- * Function: wlan_free_buffer
- *
- * Description:
- *   Insert a free Rx buffer into the free queue
- *
- * Input Parameters:
- *   priv   - Reference to the driver state structure
- *   buffer - A pointer to the packet buffer to be freed
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-static inline void wlan_free_buffer(struct wlan_priv_s *priv,
-                                    uint8_t *buffer)
-{
-  struct wlan_pktbuf_s *pktbuf;
-  irqstate_t flags;
-
-  flags = enter_critical_section();
-
-  pktbuf = container_of(buffer, struct wlan_pktbuf_s, buffer);
-  sq_addlast(&pktbuf->entry, &priv->freeb);
-
-  leave_critical_section(flags);
-}
-
 /****************************************************************************
  * Function: wlan_cache_txpkt_tail
  *
@@ -396,109 +266,8 @@ static inline void wlan_free_buffer(struct wlan_priv_s 
*priv,
 
 static inline void wlan_cache_txpkt_tail(struct wlan_priv_s *priv)
 {
-  struct wlan_pktbuf_s *pktbuf;
-  irqstate_t flags;
-  struct net_driver_s *dev = &priv->dev;
-
-  pktbuf = container_of(dev->d_buf, struct wlan_pktbuf_s, buffer);
-  pktbuf->len = dev->d_len;
-
-  flags = enter_critical_section();
-  sq_addlast(&pktbuf->entry, &priv->txb);
-  leave_critical_section(flags);
-
-  dev->d_buf = NULL;
-  dev->d_len = 0;
-}
-
-/****************************************************************************
- * Function: wlan_add_txpkt_head
- *
- * Description:
- *   Add packet into head of TX ready queue.
- *
- * Input Parameters:
- *   priv - Reference to the driver state structure
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
-
-static inline void wlan_add_txpkt_head(struct wlan_priv_s *priv,
-                                       struct wlan_pktbuf_s *pktbuf)
-{
-  irqstate_t flags;
-
-  flags = enter_critical_section();
-  sq_addfirst(&pktbuf->entry, &priv->txb);
-  leave_critical_section(flags);
-}
-
-/****************************************************************************
- * Function: wlan_recvframe
- *
- * Description:
- *   Try to receive RX packet from RX done packet queue.
- *
- * Input Parameters:
- *   priv - Reference to the driver state structure
- *
- * Returned Value:
- *   RX packet if success or NULl if no packet in queue.
- *
- ****************************************************************************/
-
-static struct wlan_pktbuf_s *wlan_recvframe(struct wlan_priv_s *priv)
-{
-  irqstate_t flags;
-  sq_entry_t *entry;
-  struct wlan_pktbuf_s *pktbuf = NULL;
-
-  flags = enter_critical_section();
-
-  entry = sq_remfirst(&priv->rxb);
-  if (entry != NULL)
-    {
-      pktbuf = container_of(entry, struct wlan_pktbuf_s, entry);
-    }
-
-  leave_critical_section(flags);
-
-  return pktbuf;
-}
-
-/****************************************************************************
- * Function: wlan_txframe
- *
- * Description:
- *   Try to receive TX buffer from TX ready buffer queue.
- *
- * Input Parameters:
- *   priv - Reference to the driver state structure
- *
- * Returned Value:
- *   TX packets buffer if success or NULL if no packet in queue.
- *
- ****************************************************************************/
-
-static struct wlan_pktbuf_s *wlan_txframe(struct wlan_priv_s *priv)
-{
-  irqstate_t flags;
-  sq_entry_t *entry;
-  struct wlan_pktbuf_s *pktbuf = NULL;
-
-  flags = enter_critical_section();
-
-  entry = sq_remfirst(&priv->txb);
-  if (entry != NULL)
-    {
-      pktbuf = container_of(entry, struct wlan_pktbuf_s, entry);
-    }
-
-  leave_critical_section(flags);
-
-  return pktbuf;
+  iob_tryadd_queue(priv->dev.d_iob, &priv->txb);
+  netdev_iob_clear(&priv->dev);
 }
 
 /****************************************************************************
@@ -518,15 +287,19 @@ static struct wlan_pktbuf_s *wlan_txframe(struct 
wlan_priv_s *priv)
 
 static void wlan_transmit(struct wlan_priv_s *priv)
 {
-  struct wlan_pktbuf_s *pktbuf;
+  uint16_t llhdrlen = NET_LL_HDRLEN(&priv->dev);
+  unsigned int offset = CONFIG_NET_LL_GUARDSIZE - llhdrlen;
+  struct iob_s *iob;
   int ret;
 
-  while ((pktbuf = wlan_txframe(priv)) != NULL)
+  while ((iob = iob_peek_queue(&priv->txb)) != NULL)
     {
-      ret = priv->ops->send(pktbuf->buffer, pktbuf->len);
+      iob_copyout(priv->flatbuf + llhdrlen, iob, iob->io_pktlen, 0);
+      memcpy(priv->flatbuf, iob->io_data + offset, llhdrlen);
+
+      ret = priv->ops->send(priv->flatbuf, iob->io_pktlen + llhdrlen);
       if (ret == -ENOMEM)
         {
-          wlan_add_txpkt_head(priv, pktbuf);
           wd_start(&priv->txtimeout, WLAN_TXTOUT,
                    wlan_txtimeout_expiry, (uint32_t)priv);
           break;
@@ -538,7 +311,11 @@ static void wlan_transmit(struct wlan_priv_s *priv)
               nwarn("WARN: Failed to send pkt, ret: %d\n", ret);
             }
 
-          wlan_free_buffer(priv, pktbuf->buffer);
+          iob_remove_queue(&priv->txb);
+
+          /* And free the I/O buffer chain */
+
+          iob_free_chain(iob);
         }
     }
 }
@@ -586,7 +363,7 @@ static void wlan_tx_done(struct wlan_priv_s *priv)
 static int wlan_rx_done(struct wlan_priv_s *priv, void *buffer,
                         uint16_t len, void *eb)
 {
-  struct wlan_pktbuf_s *pktbuf;
+  struct iob_s *iob = NULL;
   irqstate_t flags;
   int ret = 0;
 
@@ -603,25 +380,43 @@ static int wlan_rx_done(struct wlan_priv_s *priv, void 
*buffer,
       goto out;
     }
 
-  pktbuf = wlan_alloc_buffer(priv);
-  if (pktbuf == NULL)
+  if (len > iob_navail(false) * CONFIG_IOB_BUFSIZE)
     {
       ret = -ENOBUFS;
       goto out;
     }
 
-  memcpy(pktbuf->buffer, buffer, len);
-  pktbuf->len = len;
+  iob = iob_tryalloc(false);
+  if (iob == NULL)
+    {
+      ret = -ENOBUFS;
+      goto out;
+    }
 
-  if (eb != NULL)
+  ret = iob_trycopyin(iob, buffer, len, 0, false);
+  if (ret != len)
     {
-      esp_wifi_free_eb(eb);
+      ret = -ENOBUFS;
+      goto out;
     }
 
+  iob_reserve(iob, CONFIG_NET_LL_GUARDSIZE);
+
   flags = enter_critical_section();
-  sq_addlast(&pktbuf->entry, &priv->rxb);
+  ret = iob_tryadd_queue(iob, &priv->rxb);
   leave_critical_section(flags);
 
+  if (ret < 0)
+    {
+      ret = -ENOBUFS;
+      goto out;
+    }
+
+  if (eb != NULL)
+    {
+      esp_wifi_free_eb(eb);
+    }
+
   if (work_available(&priv->rxwork))
     {
       work_queue(WLAN_WORK, &priv->rxwork, wlan_rxpoll, priv, 0);
@@ -630,11 +425,18 @@ static int wlan_rx_done(struct wlan_priv_s *priv, void 
*buffer,
   return 0;
 
 out:
+  if (iob != NULL)
+    {
+      iob_free_chain(iob);
+    }
+
   if (eb != NULL)
     {
       esp_wifi_free_eb(eb);
     }
 
+  wlan_txavail(&priv->dev);
+
   return ret;
 }
 
@@ -655,32 +457,25 @@ out:
 
 static void wlan_rxpoll(void *arg)
 {
-  struct wlan_pktbuf_s *pktbuf;
-  struct eth_hdr_s *eth_hdr;
   struct wlan_priv_s *priv = (struct wlan_priv_s *)arg;
   struct net_driver_s *dev = &priv->dev;
-#ifdef WLAN_RX_THRESHOLD
-  uint32_t rbytes = 0;
-#endif
+  struct eth_hdr_s *eth_hdr;
+  struct iob_s *iob;
 
   /* Try to send all cached TX packets for TX ack and so on */
 
   wlan_transmit(priv);
 
-  /* Loop while while wlan_recvframe() successfully retrieves valid
+  /* Loop while while iob_remove_queue() successfully retrieves valid
    * Ethernet frames.
    */
 
   net_lock();
 
-  while ((pktbuf = wlan_recvframe(priv)) != NULL)
+  while ((iob = iob_remove_queue(&priv->rxb)) != NULL)
     {
-      dev->d_buf = pktbuf->buffer;
-      dev->d_len = pktbuf->len;
-
-#ifdef WLAN_RX_THRESHOLD
-      rbytes += pktbuf->len;
-#endif
+      dev->d_iob = iob;
+      dev->d_len = iob->io_pktlen;
 
 #ifdef CONFIG_NET_PKT
 
@@ -691,27 +486,9 @@ static void wlan_rxpoll(void *arg)
       pkt_input(&priv->dev);
 #endif
 
-      /* Check if the packet is a valid size for the network
-       * buffer configuration (this should not happen)
-       */
-
-      if (dev->d_len > WLAN_BUF_SIZE)
-        {
-          nwarn("WARNING: DROPPED Too big: %d\n", dev->d_len);
-
-          /* Free dropped packet buffer */
-
-          if (dev->d_buf)
-            {
-              wlan_free_buffer(priv, dev->d_buf);
-              dev->d_buf = NULL;
-              dev->d_len = 0;
-            }
-
-          continue;
-        }
-
-      eth_hdr = (struct eth_hdr_s *)dev->d_buf;
+      eth_hdr = (struct eth_hdr_s *)
+        &dev->d_iob->io_data[CONFIG_NET_LL_GUARDSIZE -
+                             NET_LL_HDRLEN(dev)];
 
       /* We only accept IP packets of the configured type and ARP packets */
 
@@ -786,34 +563,7 @@ static void wlan_rxpoll(void *arg)
           ninfo("INFO: Dropped, Unknown type: %04x\n", eth_hdr->type);
         }
 
-      /* We are finished with the RX buffer.  NOTE:  If the buffer is
-       * re-used for transmission, the dev->d_buf field will have been
-       * nullified.
-       */
-
-      if (dev->d_buf)
-        {
-          /* Free the receive packet buffer */
-
-          wlan_free_buffer(priv, dev->d_buf);
-          dev->d_buf = NULL;
-          dev->d_len = 0;
-        }
-
-#ifdef WLAN_RX_THRESHOLD
-      /**
-       * If received total bytes is larger than receive threshold,
-       * then do "unlock" to try to active applicantion to receive
-       * data from low-level buffer of IP stack.
-       */
-
-      if (rbytes >= WLAN_RX_THRESHOLD)
-        {
-          net_unlock();
-          rbytes = 0;
-          net_lock();
-        }
-#endif
+      netdev_iob_release(&priv->dev);
     }
 
   /* Try to send all cached TX packets */
@@ -845,27 +595,16 @@ static void wlan_rxpoll(void *arg)
 
 static int wlan_txpoll(struct net_driver_s *dev)
 {
-  struct wlan_pktbuf_s *pktbuf;
-  struct wlan_priv_s *priv = (struct wlan_priv_s *)dev->d_private;
-
-  DEBUGASSERT(dev->d_buf != NULL);
+  struct wlan_priv_s *priv = dev->d_private;
 
   wlan_cache_txpkt_tail(priv);
-
-  pktbuf = wlan_alloc_buffer(priv);
-  if (pktbuf == NULL)
-    {
-      return -ENOMEM;
-    }
-
-  dev->d_buf = pktbuf->buffer;
-  dev->d_len = WLAN_BUF_SIZE;
+  wlan_transmit(priv);
 
   /* If zero is returned, the polling will continue until
    * all connections have been examined.
    */
 
-  return OK;
+  return 1;
 }
 
 /****************************************************************************
@@ -890,36 +629,10 @@ static int wlan_txpoll(struct net_driver_s *dev)
 static void wlan_dopoll(struct wlan_priv_s *priv)
 {
   struct net_driver_s *dev = &priv->dev;
-  struct wlan_pktbuf_s *pktbuf;
-  uint8_t *txbuf;
-  int ret;
-
-  pktbuf = wlan_alloc_buffer(priv);
-  if (pktbuf == NULL)
-    {
-      return ;
-    }
-
-  dev->d_buf = pktbuf->buffer;
-  dev->d_len = WLAN_BUF_SIZE;
 
   /* Try to let TCP/IP to send all packets to netcard driver */
 
-  do
-    {
-      txbuf = dev->d_buf;
-      ret = devif_poll(dev, wlan_txpoll);
-    }
-  while ((ret == 0) &&
-         (dev->d_buf != txbuf));
-
-  if (dev->d_buf != NULL)
-    {
-      wlan_free_buffer(priv, dev->d_buf);
-
-      dev->d_buf = NULL;
-      dev->d_len = 0;
-    }
+  while (devif_poll(dev, wlan_txpoll));
 
   /* Try to send all cached TX packets */
 
@@ -1088,7 +801,11 @@ static int wlan_ifup(struct net_driver_s *dev)
   wlan_ipv6multicast(priv);
 #endif
 
-  wlan_init_buffer(priv);
+  IOB_QINIT(&priv->rxb);
+  IOB_QINIT(&priv->txb);
+
+  priv->dev.d_buf = NULL;
+  priv->dev.d_len = 0;
 
   priv->ifup = true;
   if (g_callback_register_ref == 0)
@@ -1141,6 +858,9 @@ static int wlan_ifdown(struct net_driver_s *dev)
 
   priv->ifup = false;
 
+  iob_free_queue(&priv->rxb);
+  iob_free_queue(&priv->txb);
+
   ret = priv->ops->stop();
   if (ret < 0)
     {
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig 
b/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
index fb48072532..16fb59816f 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
@@ -29,19 +29,24 @@ CONFIG_HAVE_CXXINITIALIZE=y
 CONFIG_IDLETHREAD_STACKSIZE=3072
 CONFIG_INIT_ENTRYPOINT="nsh_main"
 CONFIG_INTELHEX_BINARY=y
-CONFIG_LIBC_FLOATINGPOINT=y
+CONFIG_IOB_NBUFFERS=124
+CONFIG_IOB_THROTTLE=24
 CONFIG_LIBC_MAX_EXITFUNS=1
 CONFIG_NAME_MAX=48
 CONFIG_NETDB_DNSCLIENT=y
 CONFIG_NETDEV_LATEINIT=y
 CONFIG_NETDEV_PHY_IOCTL=y
 CONFIG_NETDEV_WIRELESS_IOCTL=y
+CONFIG_NETUTILS_IPERF=y
 CONFIG_NET_BROADCAST=y
 CONFIG_NET_ETH_PKTSIZE=1514
 CONFIG_NET_ICMP=y
 CONFIG_NET_ICMP_SOCKET=y
 CONFIG_NET_TCP=y
+CONFIG_NET_TCP_DELAYED_ACK=y
+CONFIG_NET_TCP_WRITE_BUFFERS=y
 CONFIG_NET_UDP=y
+CONFIG_NET_UDP_WRITE_BUFFERS=y
 CONFIG_NSH_ARCHINIT=y
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_FILEIOSIZE=512

Reply via email to