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

xiaoxiang781216 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 6569424cfa6 net/udp: Batch-copy readahead metadata
6569424cfa6 is described below

commit 6569424cfa6009a6073aa38fa88cd41a763fe4d7
Author: chao an <[email protected]>
AuthorDate: Tue Oct 27 16:34:20 2026 +0800

    net/udp: Batch-copy readahead metadata
    
    Pack the fixed UDP read-ahead metadata fields into a small local header
    before copying them into the I/O buffer chain. This reduces the number of
    IOB copy operations needed when queueing and later reading buffered UDP
    packets, while preserving the existing read-ahead layout and datagram
    semantics.
    
    Signed-off-by: chao an <[email protected]>
---
 net/udp/udp.h          | 13 +++++++++++++
 net/udp/udp_callback.c | 34 +++++++++++++---------------------
 net/udp/udp_recvfrom.c | 22 +++++++++++-----------
 3 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/net/udp/udp.h b/net/udp/udp.h
index b2688abdfbc..b30ea03941d 100644
--- a/net/udp/udp.h
+++ b/net/udp/udp.h
@@ -31,6 +31,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <stdint.h>
 
 #include <nuttx/queue.h>
 #include <nuttx/semaphore.h>
@@ -78,6 +79,18 @@
 #define UDPIPv4BUF ((FAR struct udp_hdr_s *)IPBUF(IPv4_HDRLEN))
 #define UDPIPv6BUF ((FAR struct udp_hdr_s *)IPBUF(IPv6_HDRLEN))
 
+/* UDP read-ahead metadata layout:
+ * |datalen|ifindex|src_addr_size|src_addr|[timestamp]|data|
+ */
+
+#ifdef CONFIG_NETDEV_IFINDEX
+#  define UDP_READAHEAD_META_SIZE \
+     (sizeof(uint16_t) + sizeof(uint8_t) + sizeof(uint8_t))
+#else
+#  define UDP_READAHEAD_META_SIZE \
+     (sizeof(uint16_t) + sizeof(uint8_t))
+#endif
+
 /****************************************************************************
  * Public Type Definitions
  ****************************************************************************/
diff --git a/net/udp/udp_callback.c b/net/udp/udp_callback.c
index 462910cd85f..4f8a28f7227 100644
--- a/net/udp/udp_callback.c
+++ b/net/udp/udp_callback.c
@@ -75,8 +75,10 @@ static uint16_t udp_datahandler(FAR struct net_driver_s *dev,
 #endif
 
   uint8_t src_addr_size;
+  uint8_t meta[UDP_READAHEAD_META_SIZE];
   FAR void *src_addr;
   int offset;
+  int pos;
 
   conn_lock(&conn->sconn);
 #if CONFIG_NET_RECV_BUFSIZE > 0
@@ -158,6 +160,14 @@ static uint16_t udp_datahandler(FAR struct net_driver_s 
*dev,
    * Layout: |datalen|ifindex|src_addr_size|src_addr|[timestamp]|data|
    */
 
+  pos = 0;
+  memcpy(&meta[pos], &buflen, sizeof(buflen));
+  pos += sizeof(buflen);
+#ifdef CONFIG_NETDEV_IFINDEX
+  meta[pos++] = dev->d_ifindex;
+#endif
+  meta[pos++] = src_addr_size;
+
   offset = (dev->d_appdata - iob->io_data) - iob->io_offset;
   offset -= src_addr_size;
   ret = iob_trycopyin(iob, src_addr, src_addr_size, offset, true);
@@ -166,27 +176,9 @@ static uint16_t udp_datahandler(FAR struct net_driver_s 
*dev,
       goto errout;
     }
 
-  offset -= sizeof(src_addr_size);
-  ret = iob_trycopyin(iob, &src_addr_size, sizeof(src_addr_size),
-                      offset, true);
-  if (ret < 0)
-    {
-      goto errout;
-    }
-
-#ifdef CONFIG_NETDEV_IFINDEX
-  offset -= sizeof(dev->d_ifindex);
-  ret = iob_trycopyin(iob, &dev->d_ifindex, sizeof(dev->d_ifindex),
-                      offset, true);
-  if (ret < 0)
-    {
-      goto errout;
-    }
-#endif
-
-  offset -= sizeof(buflen);
-  ret = iob_trycopyin(iob, (FAR const uint8_t *)&buflen, sizeof(buflen),
-                      offset, true);
+  DEBUGASSERT(pos == UDP_READAHEAD_META_SIZE);
+  offset -= sizeof(meta);
+  ret = iob_trycopyin(iob, meta, sizeof(meta), offset, true);
   if (ret < 0)
     {
       goto errout;
diff --git a/net/udp/udp_recvfrom.c b/net/udp/udp_recvfrom.c
index 120eba31548..aa29d4cc33f 100644
--- a/net/udp/udp_recvfrom.c
+++ b/net/udp/udp_recvfrom.c
@@ -172,9 +172,11 @@ static inline void udp_readahead(struct udp_recvfrom_s 
*pstate)
     {
       int recvlen;
       int offset = 0;
+      int pos;
       uint16_t datalen;
       uint8_t src_addr_size;
       uint8_t ifindex;
+      uint8_t meta[UDP_READAHEAD_META_SIZE];
 #ifdef CONFIG_NET_IPv6
       uint8_t srcaddr[sizeof(struct sockaddr_in6)];
 #else
@@ -185,22 +187,20 @@ static inline void udp_readahead(struct udp_recvfrom_s 
*pstate)
        * Layout: |datalen|ifindex|src_addr_size|src_addr|[timestamp]|data|
        */
 
-      recvlen = iob_copyout((FAR uint8_t *)&datalen, iob,
-                            sizeof(datalen), offset);
-      offset += sizeof(datalen);
-      DEBUGASSERT(recvlen == sizeof(datalen));
+      recvlen = iob_copyout(meta, iob, sizeof(meta), offset);
+      offset += sizeof(meta);
+      DEBUGASSERT(recvlen == sizeof(meta));
 
+      pos = 0;
+      memcpy(&datalen, &meta[pos], sizeof(datalen));
+      pos += sizeof(datalen);
 #ifdef CONFIG_NETDEV_IFINDEX
-      recvlen = iob_copyout(&ifindex, iob, sizeof(ifindex), offset);
-      offset += sizeof(ifindex);
-      DEBUGASSERT(recvlen == sizeof(ifindex));
+      ifindex = meta[pos++];
 #else
       ifindex = 1;
 #endif
-      recvlen = iob_copyout(&src_addr_size, iob,
-                            sizeof(src_addr_size), offset);
-      offset += sizeof(src_addr_size);
-      DEBUGASSERT(recvlen == sizeof(src_addr_size));
+      src_addr_size = meta[pos++];
+      DEBUGASSERT(pos == UDP_READAHEAD_META_SIZE);
 
       recvlen = iob_copyout(srcaddr, iob, src_addr_size, offset);
       offset += src_addr_size;

Reply via email to