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;