mm/iob: Add support for increasing length in iob_update_pktlen
Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
parent
2fa68fbddd
commit
d44e19d115
@ -1290,12 +1290,17 @@ FAR uint8_t *netpkt_getbase(FAR netpkt_t *pkt)
|
||||
* pkt - The net packet
|
||||
* len - The length of data in netpkt
|
||||
*
|
||||
* Returned Value:
|
||||
* The new effective data length, or a negated errno value on error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void netpkt_setdatalen(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt, unsigned int len)
|
||||
int netpkt_setdatalen(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt, unsigned int len)
|
||||
{
|
||||
iob_update_pktlen(pkt, len - NET_LL_HDRLEN(&dev->netdev));
|
||||
uint8_t llhdrlen = NET_LL_HDRLEN(&dev->netdev);
|
||||
int ret = iob_update_pktlen(pkt, len - llhdrlen, false);
|
||||
return ret >= 0 ? ret + llhdrlen : ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -571,14 +571,16 @@ void iob_reserve(FAR struct iob_s *iob, unsigned int reserved);
|
||||
*
|
||||
* Description:
|
||||
* This function will update packet length of the iob, it will be
|
||||
* trimmed if the length of the iob chain is greater than the current
|
||||
* length.
|
||||
* This function will not grow the iob link, any grow operation should
|
||||
* be implemented through iob_copyin()/iob_trycopyin().
|
||||
* trimmed if the current length of the iob chain is greater than the
|
||||
* new length, and will be grown if less than new length.
|
||||
*
|
||||
* Returned Value:
|
||||
* The new effective iob packet length, or a negated errno value on error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void iob_update_pktlen(FAR struct iob_s *iob, unsigned int pktlen);
|
||||
int iob_update_pktlen(FAR struct iob_s *iob, unsigned int pktlen,
|
||||
bool throttled);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: iob_count
|
||||
|
@ -422,10 +422,13 @@ FAR uint8_t *netpkt_getbase(FAR netpkt_t *pkt);
|
||||
* pkt - The net packet
|
||||
* len - The length of data in netpkt
|
||||
*
|
||||
* Returned Value:
|
||||
* The new effective data length, or a negated errno value on error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void netpkt_setdatalen(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt, unsigned int len);
|
||||
int netpkt_setdatalen(FAR struct netdev_lowerhalf_s *dev,
|
||||
FAR netpkt_t *pkt, unsigned int len);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netpkt_getdatalen
|
||||
|
@ -36,14 +36,16 @@
|
||||
*
|
||||
* Description:
|
||||
* This function will update packet length of the iob, it will be
|
||||
* trimmed if the length of the iob chain is greater than the current
|
||||
* length.
|
||||
* This function will not grow the iob link, any grow operation should
|
||||
* be implemented through iob_copyin()/iob_trycopyin().
|
||||
* trimmed if the current length of the iob chain is greater than the
|
||||
* new length, and will be grown if less than new length.
|
||||
*
|
||||
* Returned Value:
|
||||
* The new effective iob packet length, or a negated errno value on error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void iob_update_pktlen(FAR struct iob_s *iob, unsigned int pktlen)
|
||||
int iob_update_pktlen(FAR struct iob_s *iob, unsigned int pktlen,
|
||||
bool throttled)
|
||||
{
|
||||
FAR struct iob_s *penultimate;
|
||||
FAR struct iob_s *next;
|
||||
@ -56,7 +58,7 @@ void iob_update_pktlen(FAR struct iob_s *iob, unsigned int pktlen)
|
||||
|
||||
if (iob == NULL)
|
||||
{
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Calculate the total entries of the data in the I/O buffer chain */
|
||||
@ -66,7 +68,8 @@ void iob_update_pktlen(FAR struct iob_s *iob, unsigned int pktlen)
|
||||
{
|
||||
ninqueue++;
|
||||
offset += next->io_offset;
|
||||
next = next->io_flink;
|
||||
penultimate = next;
|
||||
next = next->io_flink;
|
||||
}
|
||||
|
||||
/* Trim inqueue entries if needed */
|
||||
@ -104,6 +107,21 @@ void iob_update_pktlen(FAR struct iob_s *iob, unsigned int pktlen)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (nrequire > ninqueue)
|
||||
{
|
||||
/* Start from the last IOB */
|
||||
|
||||
next = penultimate;
|
||||
|
||||
/* Loop to extend the link */
|
||||
|
||||
while (next != NULL && nrequire > ninqueue)
|
||||
{
|
||||
next->io_flink = iob_tryalloc(throttled);
|
||||
next = next->io_flink;
|
||||
ninqueue++;
|
||||
}
|
||||
}
|
||||
|
||||
iob->io_pktlen = pktlen;
|
||||
|
||||
@ -125,4 +143,10 @@ void iob_update_pktlen(FAR struct iob_s *iob, unsigned int pktlen)
|
||||
pktlen -= len;
|
||||
next = next->io_flink;
|
||||
}
|
||||
|
||||
/* Adjust final pktlen if it's not fully increased (e.g. alloc fail) */
|
||||
|
||||
iob->io_pktlen -= pktlen;
|
||||
|
||||
return iob->io_pktlen;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ void arp_format(FAR struct net_driver_s *dev, in_addr_t ipaddr)
|
||||
|
||||
/* Update device buffer length */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, sizeof(struct arp_hdr_s));
|
||||
iob_update_pktlen(dev->d_iob, sizeof(struct arp_hdr_s), false);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_ARP */
|
||||
|
@ -92,7 +92,7 @@ int devif_file_send(FAR struct net_driver_s *dev, FAR struct file *file,
|
||||
goto errout;
|
||||
}
|
||||
|
||||
iob_update_pktlen(dev->d_iob, target_offset);
|
||||
iob_update_pktlen(dev->d_iob, target_offset, false);
|
||||
|
||||
ret = file_seek(file, offset, SEEK_SET);
|
||||
if (ret < 0)
|
||||
@ -142,7 +142,7 @@ int devif_file_send(FAR struct net_driver_s *dev, FAR struct file *file,
|
||||
}
|
||||
}
|
||||
|
||||
iob_update_pktlen(dev->d_iob, target_offset + len);
|
||||
iob_update_pktlen(dev->d_iob, target_offset + len, false);
|
||||
|
||||
dev->d_sndlen = len;
|
||||
return len;
|
||||
|
@ -704,7 +704,7 @@ static int devif_poll_ipfrag(FAR struct net_driver_s *dev,
|
||||
|
||||
if (!bstop && reused)
|
||||
{
|
||||
iob_update_pktlen(dev->d_iob, 0);
|
||||
iob_update_pktlen(dev->d_iob, 0, false);
|
||||
netdev_iob_prepare(dev, true, 0);
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ int devif_send(FAR struct net_driver_s *dev, FAR const void *buf,
|
||||
|
||||
/* Prepare device buffer before poll callback */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, offset);
|
||||
iob_update_pktlen(dev->d_iob, offset, false);
|
||||
|
||||
ret = iob_trycopyin(dev->d_iob, buf, len, offset, false);
|
||||
if (ret != len)
|
||||
|
@ -207,7 +207,7 @@ static int ipv4_in(FAR struct net_driver_s *dev)
|
||||
totlen = (ipv4->len[0] << 8) + ipv4->len[1];
|
||||
if (totlen < dev->d_len)
|
||||
{
|
||||
iob_update_pktlen(dev->d_iob, totlen);
|
||||
iob_update_pktlen(dev->d_iob, totlen, false);
|
||||
dev->d_len = totlen;
|
||||
}
|
||||
else if (totlen > dev->d_len)
|
||||
|
@ -256,7 +256,7 @@ static int ipv6_in(FAR struct net_driver_s *dev)
|
||||
|
||||
if (paylen < dev->d_len)
|
||||
{
|
||||
iob_update_pktlen(dev->d_iob, paylen);
|
||||
iob_update_pktlen(dev->d_iob, paylen, false);
|
||||
dev->d_len = paylen;
|
||||
}
|
||||
else if (paylen > dev->d_len)
|
||||
|
@ -133,7 +133,7 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code)
|
||||
|
||||
/* Skip icmp header from iob */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, datalen + ipicmplen);
|
||||
iob_update_pktlen(dev->d_iob, datalen + ipicmplen, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -167,8 +167,9 @@ void icmp_reply(FAR struct net_driver_s *dev, int type, int code)
|
||||
|
||||
/* Skip icmp header from iob */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, dev->d_iob->io_pktlen +
|
||||
sizeof(struct icmp_hdr_s));
|
||||
iob_update_pktlen(dev->d_iob,
|
||||
dev->d_iob->io_pktlen + sizeof(struct icmp_hdr_s),
|
||||
false);
|
||||
|
||||
/* Concat new icmp packet before original datagram */
|
||||
|
||||
|
@ -105,7 +105,7 @@ void icmpv6_advertise(FAR struct net_driver_s *dev,
|
||||
|
||||
/* Update device buffer length */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size);
|
||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size, false);
|
||||
|
||||
/* Calculate the checksum over both the ICMP header and payload */
|
||||
|
||||
|
@ -282,7 +282,7 @@ void icmpv6_radvertise(FAR struct net_driver_s *dev)
|
||||
|
||||
/* Update device buffer length */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size);
|
||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size, false);
|
||||
|
||||
/* Calculate the checksum over both the ICMP header and payload */
|
||||
|
||||
|
@ -122,7 +122,7 @@ void icmpv6_reply(FAR struct net_driver_s *dev, int type, int code, int data)
|
||||
|
||||
/* Skip icmp header from iob */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, datalen + ipicmplen);
|
||||
iob_update_pktlen(dev->d_iob, datalen + ipicmplen, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -156,8 +156,9 @@ void icmpv6_reply(FAR struct net_driver_s *dev, int type, int code, int data)
|
||||
|
||||
/* Skip icmp header from iob */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, dev->d_iob->io_pktlen +
|
||||
sizeof(struct icmpv6_hdr_s));
|
||||
iob_update_pktlen(dev->d_iob,
|
||||
dev->d_iob->io_pktlen + sizeof(struct icmpv6_hdr_s),
|
||||
false);
|
||||
|
||||
/* Concat new icmp packet before original datagram */
|
||||
|
||||
|
@ -99,7 +99,7 @@ void icmpv6_rsolicit(FAR struct net_driver_s *dev)
|
||||
|
||||
/* Update device buffer length */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size);
|
||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size, false);
|
||||
|
||||
/* Calculate the checksum over both the ICMP header and payload */
|
||||
|
||||
|
@ -122,7 +122,7 @@ void icmpv6_solicit(FAR struct net_driver_s *dev,
|
||||
|
||||
/* Update device buffer length */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size);
|
||||
iob_update_pktlen(dev->d_iob, IPv6_HDRLEN + l3size, false);
|
||||
|
||||
/* Calculate the checksum over both the ICMP header and payload */
|
||||
|
||||
|
@ -129,7 +129,7 @@ void igmp_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group,
|
||||
|
||||
/* Update device buffer length */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len);
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len, false);
|
||||
|
||||
/* The total size of the data is the size of the IGMP header */
|
||||
|
||||
|
@ -168,7 +168,7 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
|
||||
|
||||
/* Update device buffer length */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len);
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len, false);
|
||||
|
||||
/* Select the IPv6 destination address.
|
||||
* This varies with the type of message being sent:
|
||||
|
@ -170,7 +170,7 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
|
||||
|
||||
/* Update device buffer length before setup the IP header */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len);
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len, false);
|
||||
|
||||
/* Calculate chk & build L3 header */
|
||||
|
||||
@ -464,7 +464,7 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
|
||||
|
||||
/* Update device buffer length before setup the IP header */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len);
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len, false);
|
||||
|
||||
/* Calculate chk & build L3 header */
|
||||
|
||||
|
@ -174,7 +174,7 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
|
||||
|
||||
/* Update the device buffer length */
|
||||
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len);
|
||||
iob_update_pktlen(dev->d_iob, dev->d_len, false);
|
||||
|
||||
#ifdef CONFIG_NET_UDP_CHECKSUMS
|
||||
/* Calculate UDP checksum. */
|
||||
|
@ -790,7 +790,7 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf,
|
||||
udpiplen = udpip_hdrsize(conn);
|
||||
|
||||
iob_reserve(wrb->wb_iob, CONFIG_NET_LL_GUARDSIZE);
|
||||
iob_update_pktlen(wrb->wb_iob, udpiplen);
|
||||
iob_update_pktlen(wrb->wb_iob, udpiplen, false);
|
||||
|
||||
/* Copy the user data into the write buffer. We cannot wait for
|
||||
* buffer space if the socket was opened non-blocking.
|
||||
|
Loading…
Reference in New Issue
Block a user