You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/01/30 16:39:22 UTC

[nuttx] branch master updated (0f35ad29a8 -> ff68d9ac04)

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

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


    from 0f35ad29a8 arm/unwinder: set default unwinder type to arm exidx/extab
     new be89bcc044 mm/iob: Support negative offset when copyin/out.
     new ff68d9ac04 net/tun: Change TUN/TAP to use IOB

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 drivers/net/tun.c         | 77 ++++++++++++++++++++++++++++++-----------------
 include/nuttx/mm/iob.h    |  6 ++--
 mm/iob/iob_copyin.c       | 21 ++++++++-----
 mm/iob/iob_copyout.c      | 13 ++++++--
 net/devif/devif_poll.c    |  7 +----
 net/netdev/netdev_input.c | 23 +++-----------
 6 files changed, 83 insertions(+), 64 deletions(-)


[nuttx] 02/02: net/tun: Change TUN/TAP to use IOB

Posted by xi...@apache.org.
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

commit ff68d9ac04bdf20a12b8420b622f3cef282459d2
Author: Zhe Weng <we...@xiaomi.com>
AuthorDate: Tue Jan 10 20:03:02 2023 +0800

    net/tun: Change TUN/TAP to use IOB
    
    TUN/TAP is not working after IOB offload, try to fix.
    
    Signed-off-by: Zhe Weng <we...@xiaomi.com>
---
 drivers/net/tun.c | 77 +++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 49 insertions(+), 28 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 47d32be57d..65e54fcdb1 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -61,6 +61,8 @@
 #include <nuttx/irq.h>
 #include <nuttx/mutex.h>
 #include <nuttx/wqueue.h>
+#include <nuttx/mm/iob.h>
+#include <nuttx/net/net.h>
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/ethernet.h>
 #include <nuttx/net/tun.h>
@@ -98,12 +100,6 @@
 #  define CONFIG_TUN_NINTERFACES 1
 #endif
 
-/* Make sure that packet buffers include in configured guard size and are an
- * even multiple of 16-bits in length.
- */
-
-#define NET_TUN_PKTSIZE ((CONFIG_NET_TUN_PKTSIZE + CONFIG_NET_GUARDSIZE + 1) & ~1)
-
 /* This is a helper pointer for accessing the contents of the Ethernet
  * header.
  */
@@ -137,8 +133,8 @@ struct tun_device_s
    * is assured only by the preceding wide data types.
    */
 
-  uint8_t           read_buf[NET_TUN_PKTSIZE];
-  uint8_t           write_buf[NET_TUN_PKTSIZE];
+  FAR struct iob_s *read_buf;
+  FAR struct iob_s *write_buf;
 
   /* This holds the information visible to the NuttX network */
 
@@ -310,8 +306,14 @@ static void tun_fd_transmit(FAR struct tun_device_s *priv)
 
 static int tun_txpoll(FAR struct net_driver_s *dev)
 {
+  FAR struct tun_device_s *priv = (FAR struct tun_device_s *)dev->d_private;
   int ret;
 
+  DEBUGASSERT(priv->read_buf == NULL);
+  priv->read_d_len = dev->d_len;
+  priv->read_buf   = dev->d_iob;
+  netdev_iob_clear(dev);
+
 #ifdef CONFIG_NET_ETHERNET
   if (dev->d_lltype == NET_LL_ETHERNET)
     {
@@ -358,7 +360,6 @@ static int tun_txpoll_tap(FAR struct net_driver_s *dev)
 
   /* Send the packet */
 
-  priv->read_d_len = priv->dev.d_len;
   tun_fd_transmit(priv);
 
   return 1;
@@ -394,7 +395,6 @@ static int tun_txpoll_tun(FAR struct net_driver_s *dev)
 {
   FAR struct tun_device_s *priv = (FAR struct tun_device_s *)dev->d_private;
 
-  priv->read_d_len = priv->dev.d_len;
   tun_fd_transmit(priv);
 
   return 1;
@@ -495,17 +495,6 @@ static void tun_net_receive_tap(FAR struct tun_device_s *priv)
     {
       arp_input(&priv->dev);
       NETDEV_RXARP(&priv->dev);
-
-      /* If the above function invocation resulted in data that should be
-       * sent out on the network, the field d_len will set to a value > 0.
-       */
-
-      if (priv->dev.d_len > 0)
-        {
-          priv->write_d_len = priv->dev.d_len;
-          tun_fd_transmit(priv);
-          priv->dev.d_len = 0;
-        }
     }
   else
 #endif
@@ -522,7 +511,10 @@ static void tun_net_receive_tap(FAR struct tun_device_s *priv)
     {
       /* And send the packet */
 
+      DEBUGASSERT(priv->write_buf == NULL);
       priv->write_d_len = priv->dev.d_len;
+      priv->write_buf   = priv->dev.d_iob;
+      netdev_iob_clear(&priv->dev);
       tun_fd_transmit(priv);
     }
 }
@@ -599,7 +591,10 @@ static void tun_net_receive_tun(FAR struct tun_device_s *priv)
 
   if (dev->d_len > 0)
     {
+      DEBUGASSERT(priv->write_buf == NULL);
       priv->write_d_len = dev->d_len;
+      priv->write_buf   = dev->d_iob;
+      netdev_iob_clear(dev);
       tun_fd_transmit(priv);
     }
 }
@@ -629,7 +624,6 @@ static void tun_txdone(FAR struct tun_device_s *priv)
 
   /* Then poll the network for new XMIT data */
 
-  priv->dev.d_buf = priv->read_buf;
   devif_poll(&priv->dev, tun_txpoll);
 }
 
@@ -751,7 +745,6 @@ static void tun_txavail_work(FAR void *arg)
     {
       /* Poll the network for new XMIT data */
 
-      priv->dev.d_buf = priv->read_buf;
       devif_poll(&priv->dev, tun_txpoll);
     }
 
@@ -965,6 +958,7 @@ static ssize_t tun_write(FAR struct file *filep, FAR const char *buffer,
 {
   FAR struct tun_device_s *priv = filep->f_priv;
   ssize_t nwritten = 0;
+  uint8_t llhdrlen;
   int ret;
 
   if (priv == NULL || buflen > CONFIG_NET_TUN_PKTSIZE)
@@ -972,6 +966,8 @@ static ssize_t tun_write(FAR struct file *filep, FAR const char *buffer,
       return -EINVAL;
     }
 
+  llhdrlen = NET_LL_HDRLEN(&priv->dev);
+
   for (; ; )
     {
       /* Write must return immediately if interrupted by a signal (or if the
@@ -988,10 +984,24 @@ static ssize_t tun_write(FAR struct file *filep, FAR const char *buffer,
 
       if (priv->write_d_len == 0)
         {
-          memcpy(priv->write_buf, buffer, buflen);
-
           net_lock();
-          priv->dev.d_buf = priv->write_buf;
+          ret = netdev_iob_prepare(&priv->dev, false, 0);
+          if (ret < 0)
+            {
+              nwritten = (nwritten == 0) ? ret : nwritten;
+              net_unlock();
+              break;
+            }
+
+          ret = iob_trycopyin(priv->dev.d_iob, (FAR const uint8_t *)buffer,
+                              buflen, -llhdrlen, false);
+          if (ret < 0)
+            {
+              nwritten = (nwritten == 0) ? ret : nwritten;
+              net_unlock();
+              break;
+            }
+
           priv->dev.d_len = buflen;
 
           tun_net_receive(priv);
@@ -1027,6 +1037,7 @@ static ssize_t tun_read(FAR struct file *filep, FAR char *buffer,
 {
   FAR struct tun_device_s *priv = filep->f_priv;
   ssize_t nread = 0;
+  uint8_t llhdrlen;
   int ret;
 
   if (priv == NULL)
@@ -1034,6 +1045,8 @@ static ssize_t tun_read(FAR struct file *filep, FAR char *buffer,
       return -EINVAL;
     }
 
+  llhdrlen = NET_LL_HDRLEN(&priv->dev);
+
   for (; ; )
     {
       /* Read must return immediately if interrupted by a signal (or if the
@@ -1056,8 +1069,12 @@ static ssize_t tun_read(FAR struct file *filep, FAR char *buffer,
               break;
             }
 
-          memcpy(buffer, priv->write_buf, priv->write_d_len);
+          iob_copyout((FAR uint8_t *)buffer, priv->write_buf,
+                      priv->write_d_len, -llhdrlen);
           nread = priv->write_d_len;
+
+          iob_free_chain(priv->write_buf);
+          priv->write_buf   = NULL;
           priv->write_d_len = 0;
 
           NETDEV_TXDONE(&priv->dev);
@@ -1075,8 +1092,12 @@ static ssize_t tun_read(FAR struct file *filep, FAR char *buffer,
               break;
             }
 
-          memcpy(buffer, priv->read_buf, priv->read_d_len);
+          iob_copyout((FAR uint8_t *)buffer, priv->read_buf,
+                      priv->read_d_len, -llhdrlen);
           nread = priv->read_d_len;
+
+          iob_free_chain(priv->read_buf);
+          priv->read_buf   = NULL;
           priv->read_d_len = 0;
 
           net_lock();


[nuttx] 01/02: mm/iob: Support negative offset when copyin/out.

Posted by xi...@apache.org.
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

commit be89bcc0445eba4101d09960f0b58ee63824dbfd
Author: Zhe Weng <we...@xiaomi.com>
AuthorDate: Wed Jan 18 19:58:52 2023 +0800

    mm/iob: Support negative offset when copyin/out.
    
    Signed-off-by: Zhe Weng <we...@xiaomi.com>
---
 include/nuttx/mm/iob.h    |  6 +++---
 mm/iob/iob_copyin.c       | 21 ++++++++++++++-------
 mm/iob/iob_copyout.c      | 13 +++++++++++--
 net/devif/devif_poll.c    |  7 +------
 net/netdev/netdev_input.c | 23 +++++------------------
 5 files changed, 34 insertions(+), 36 deletions(-)

diff --git a/include/nuttx/mm/iob.h b/include/nuttx/mm/iob.h
index ee3987d086..ede9816f9e 100644
--- a/include/nuttx/mm/iob.h
+++ b/include/nuttx/mm/iob.h
@@ -405,7 +405,7 @@ unsigned int iob_get_queue_size(FAR struct iob_queue_s *queue);
  ****************************************************************************/
 
 int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
-               unsigned int len, unsigned int offset, bool throttled);
+               unsigned int len, int offset, bool throttled);
 
 /****************************************************************************
  * Name: iob_trycopyin
@@ -418,7 +418,7 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
  ****************************************************************************/
 
 int iob_trycopyin(FAR struct iob_s *iob, FAR const uint8_t *src,
-                  unsigned int len, unsigned int offset, bool throttled);
+                  unsigned int len, int offset, bool throttled);
 
 /****************************************************************************
  * Name: iob_copyout
@@ -430,7 +430,7 @@ int iob_trycopyin(FAR struct iob_s *iob, FAR const uint8_t *src,
  ****************************************************************************/
 
 int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob,
-                unsigned int len, unsigned int offset);
+                unsigned int len, int offset);
 
 /****************************************************************************
  * Name: iob_tailroom
diff --git a/mm/iob/iob_copyin.c b/mm/iob/iob_copyin.c
index 039cd923bd..0d221ee3b9 100644
--- a/mm/iob/iob_copyin.c
+++ b/mm/iob/iob_copyin.c
@@ -51,7 +51,7 @@
  ****************************************************************************/
 
 static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src,
-                               unsigned int len, unsigned int offset,
+                               unsigned int len, int offset,
                                bool throttled, bool can_block)
 {
   FAR struct iob_s *head = iob;
@@ -61,23 +61,30 @@ static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src,
   unsigned int avail;
   unsigned int total = len;
 
-  iobinfo("iob=%p len=%u offset=%u\n", iob, len, offset);
+  iobinfo("iob=%p len=%u offset=%d\n", iob, len, offset);
   DEBUGASSERT(iob && src);
 
   /* The offset must applied to data that is already in the I/O buffer
    * chain
    */
 
-  if (offset > iob->io_pktlen)
+  if ((int)(offset - iob->io_pktlen) > 0)
     {
-      ioberr("ERROR: offset is past the end of data: %u > %u\n",
+      ioberr("ERROR: offset is past the end of data: %d > %u\n",
              offset, iob->io_pktlen);
       return -ESPIPE;
     }
 
+  if ((int)(offset + iob->io_offset) < 0)
+    {
+      ioberr("ERROR: offset is before the start of data: %d < %d\n",
+             offset, -(int)iob->io_offset);
+      return -ESPIPE;
+    }
+
   /* Skip to the I/O buffer containing the data offset */
 
-  while (offset > iob->io_len)
+  while ((int)(offset - iob->io_len) > 0)
     {
       offset -= iob->io_len;
       iob     = iob->io_flink;
@@ -216,7 +223,7 @@ static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src,
  ****************************************************************************/
 
 int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
-               unsigned int len, unsigned int offset, bool throttled)
+               unsigned int len, int offset, bool throttled)
 {
   return iob_copyin_internal(iob, src, len, offset, throttled, true);
 }
@@ -232,7 +239,7 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
  ****************************************************************************/
 
 int iob_trycopyin(FAR struct iob_s *iob, FAR const uint8_t *src,
-                  unsigned int len, unsigned int offset, bool throttled)
+                  unsigned int len, int offset, bool throttled)
 {
   return iob_copyin_internal(iob, src, len, offset, throttled, false);
 }
diff --git a/mm/iob/iob_copyout.c b/mm/iob/iob_copyout.c
index 5d9643c750..a32e777d10 100644
--- a/mm/iob/iob_copyout.c
+++ b/mm/iob/iob_copyout.c
@@ -54,16 +54,25 @@
  ****************************************************************************/
 
 int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob,
-                unsigned int len, unsigned int offset)
+                unsigned int len, int offset)
 {
   FAR const uint8_t *src;
   unsigned int ncopy;
   unsigned int avail;
   unsigned int remaining;
 
+  /* The offset must applied to data that is in the I/O buffer chain */
+
+  if ((int)(offset + iob->io_offset) < 0)
+    {
+      ioberr("ERROR: offset is before the start of data: %d < %d\n",
+             offset, -(int)iob->io_offset);
+      return -ESPIPE;
+    }
+
   /* Skip to the I/O buffer containing the offset */
 
-  while (offset >= iob->io_len)
+  while ((int)(offset - iob->io_len) >= 0)
     {
       offset -= iob->io_len;
       iob     = iob->io_flink;
diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c
index 7eb4e49776..5cf78a6949 100644
--- a/net/devif/devif_poll.c
+++ b/net/devif/devif_poll.c
@@ -1004,12 +1004,7 @@ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
         {
           /* Copy iob to flat buffer */
 
-          iob_copyout(buf + llhdrlen,
-                      dev->d_iob, dev->d_len, 0);
-
-          /* Copy l2 header (arp out) */
-
-          memcpy(buf, IPBUF(-llhdrlen), llhdrlen);
+          iob_copyout(buf, dev->d_iob, dev->d_len, -llhdrlen);
 
           /* Restore flat buffer pointer */
 
diff --git a/net/netdev/netdev_input.c b/net/netdev/netdev_input.c
index 45a63d7176..85aa6e7e57 100644
--- a/net/netdev/netdev_input.c
+++ b/net/netdev/netdev_input.c
@@ -68,8 +68,6 @@ int netdev_input(FAR struct net_driver_s *dev,
 {
   uint16_t llhdrlen = NET_LL_HDRLEN(dev);
   FAR uint8_t *buf = dev->d_buf;
-  unsigned int offset;
-  unsigned int l3l4len;
   int ret;
 
   /* Prepare iob buffer */
@@ -80,32 +78,21 @@ int netdev_input(FAR struct net_driver_s *dev,
       return ret;
     }
 
-  /* Copy l2 header to gruard area */
+  /* Copy data to iob entry */
 
-  offset = dev->d_iob->io_offset - llhdrlen;
-  memcpy(dev->d_iob->io_data + offset, buf, llhdrlen);
-
-  /* Copy l3/l4 data to iob entry */
-
-  l3l4len = dev->d_len - llhdrlen;
-
-  ret = iob_trycopyin(dev->d_iob, buf + llhdrlen,
-                      l3l4len, 0, false);
-  if (ret == l3l4len)
+  ret = iob_trycopyin(dev->d_iob, buf, dev->d_len, -llhdrlen, false);
+  if (ret == dev->d_len)
     {
       /* Update device buffer to l2 start */
 
-      dev->d_buf = dev->d_iob->io_data + offset;
-
-      iob_update_pktlen(dev->d_iob, l3l4len);
+      dev->d_buf = NETLLBUF;
 
       ret = callback(dev);
       if (dev->d_iob != NULL && reply)
         {
           if (ret == OK && dev->d_len > 0)
             {
-              iob_copyout(buf + llhdrlen, dev->d_iob, dev->d_len, 0);
-              memcpy(buf, dev->d_iob->io_data + offset, llhdrlen);
+              iob_copyout(buf, dev->d_iob, dev->d_len, -llhdrlen);
             }
         }
     }