Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: Fix task block when devif_send fails. #9423

Merged
merged 1 commit into from Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions net/can/can_sendmsg.c
Expand Up @@ -106,11 +106,13 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
{
/* Copy the packet data into the device packet buffer and send it */

devif_send(dev, pstate->snd_buffer, pstate->snd_buflen, 0);
int ret = devif_send(dev, pstate->snd_buffer,
pstate->snd_buflen, 0);
dev->d_len = dev->d_sndlen;
xiaoxiang781216 marked this conversation as resolved.
Show resolved Hide resolved
if (dev->d_sndlen == 0)
if (ret <= 0)
{
return flags;
pstate->snd_sent = ret;
goto end_wait;
}

pstate->snd_sent = pstate->snd_buflen;
Expand All @@ -122,6 +124,8 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
}
}

end_wait:

/* Don't allow any further call backs. */

pstate->snd_cb->flags = 0;
Expand Down
41 changes: 25 additions & 16 deletions net/devif/devif.h
Expand Up @@ -432,31 +432,40 @@ uint16_t devif_conn_event(FAR struct net_driver_s *dev, uint16_t flags,
uint16_t devif_dev_event(FAR struct net_driver_s *dev, uint16_t flags);

/****************************************************************************
* Send data on the current connection.
* Name: devif_send
*
* This function is used to send out a single segment of TCP data. Only
* socket logic that have been invoked by the lower level for event
* processing can send data.
* Description:
* Send data on the current connection.
*
* This function is used to send out a single segment of TCP data. Only
* socket logic that have been invoked by the lower level for event
* processing can send data.
*
* The amount of data that actually is sent out after a call to this
* function is determined by the maximum amount of data TCP allows. The
* network will automatically crop the data so that only the appropriate
* amount of data is sent. The mss field of the TCP connection structure
* can be used to determine the amount of data that actually will be sent.
* The amount of data that actually is sent out after a call to this
* function is determined by the maximum amount of data TCP allows. The
* network will automatically crop the data so that only the appropriate
* amount of data is sent. The mss field of the TCP connection structure
* can be used to determine the amount of data that actually will be sent.
*
* Note: This function does not guarantee that the sent data will
* arrive at the destination. If the data is lost in the network, the
* TCP socket layer will be invoked with the TCP_REXMIT flag set. The
* socket layer will then have to resend the data using this function.
*
* data A pointer to the data which is to be sent.
* Input Parameters:
* dev - The network device state structure associated with the network
* device that initiated the callback event.
* buf - A pointer to the data which is to be sent.
* len - The maximum amount of data bytes to be sent.
* offset - Offset of data in buffer.
*
* len The maximum amount of data bytes to be sent.
* Returned Value:
* The amount of data sent, or negated ERRNO in case of failure.
*
****************************************************************************/

void devif_send(FAR struct net_driver_s *dev, FAR const void *buf,
int len, unsigned int offset);
int devif_send(FAR struct net_driver_s *dev, FAR const void *buf,
int len, unsigned int offset);

/****************************************************************************
* Name: devif_iob_send
Expand All @@ -475,9 +484,9 @@ void devif_send(FAR struct net_driver_s *dev, FAR const void *buf,

#ifdef CONFIG_MM_IOB
struct iob_s;
void devif_iob_send(FAR struct net_driver_s *dev, FAR struct iob_s *buf,
unsigned int len, unsigned int offset,
unsigned int target_offset);
int devif_iob_send(FAR struct net_driver_s *dev, FAR struct iob_s *buf,
unsigned int len, unsigned int offset,
unsigned int target_offset);
#endif

/****************************************************************************
Expand Down
9 changes: 5 additions & 4 deletions net/devif/devif_iobsend.c
Expand Up @@ -53,9 +53,9 @@
*
****************************************************************************/

void devif_iob_send(FAR struct net_driver_s *dev, FAR struct iob_s *iob,
unsigned int len, unsigned int offset,
unsigned int target_offset)
int devif_iob_send(FAR struct net_driver_s *dev, FAR struct iob_s *iob,
unsigned int len, unsigned int offset,
unsigned int target_offset)
{
int ret;

Expand Down Expand Up @@ -105,10 +105,11 @@ void devif_iob_send(FAR struct net_driver_s *dev, FAR struct iob_s *iob,
lib_dumpbuffer("devif_iob_send", dev->d_appdata, len);
#endif

return;
return dev->d_sndlen;

errout:
nerr("ERROR: devif_iob_send error: %d\n", ret);
return ret;
}

#endif /* CONFIG_MM_IOB */
7 changes: 4 additions & 3 deletions net/devif/devif_send.c
Expand Up @@ -66,8 +66,8 @@
*
****************************************************************************/

void devif_send(FAR struct net_driver_s *dev, FAR const void *buf,
int len, unsigned int offset)
int devif_send(FAR struct net_driver_s *dev, FAR const void *buf,
int len, unsigned int offset)
{
int ret;

Expand Down Expand Up @@ -113,8 +113,9 @@ void devif_send(FAR struct net_driver_s *dev, FAR const void *buf,

dev->d_sndlen = len;

return;
return dev->d_sndlen;

errout:
nerr("ERROR: devif_send error: %d\n", ret);
return ret;
}
10 changes: 7 additions & 3 deletions net/pkt/pkt_sendmsg.c
Expand Up @@ -105,10 +105,12 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
{
/* Copy the packet data into the device packet buffer and send it */

devif_send(dev, pstate->snd_buffer, pstate->snd_buflen, 0);
if (dev->d_sndlen == 0)
int ret = devif_send(dev, pstate->snd_buffer,
pstate->snd_buflen, 0);
if (ret <= 0)
{
return flags;
pstate->snd_sent = ret;
goto end_wait;
}

pstate->snd_sent = pstate->snd_buflen;
Expand All @@ -120,6 +122,8 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
IFF_SET_NOARP(dev->d_flags);
}

end_wait:

/* Don't allow any further call backs. */

pstate->snd_cb->flags = 0;
Expand Down
14 changes: 8 additions & 6 deletions net/tcp/tcp_send_buffered.c
Expand Up @@ -690,6 +690,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
FAR sq_entry_t *entry;
FAR sq_entry_t *next;
size_t sndlen;
int ret;

/* According to RFC 6298 (5.4), retransmit the earliest segment
* that has not been acknowledged by the TCP receiver.
Expand Down Expand Up @@ -737,9 +738,9 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,

tcp_setsequence(conn->sndseq, TCP_WBSEQNO(wrb));

devif_iob_send(dev, TCP_WBIOB(wrb), sndlen,
0, tcpip_hdrsize(conn));
if (dev->d_sndlen == 0)
ret = devif_iob_send(dev, TCP_WBIOB(wrb), sndlen,
0, tcpip_hdrsize(conn));
if (ret <= 0)
{
return flags;
}
Expand Down Expand Up @@ -969,6 +970,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
if (TCP_SEQ_LT(seq, snd_wnd_edge))
{
uint32_t remaining_snd_wnd;
int ret;

sndlen = TCP_WBPKTLEN(wrb) - TCP_WBSENT(wrb);
if (sndlen > conn->mss)
Expand Down Expand Up @@ -1012,9 +1014,9 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
* won't actually happen until the polling cycle completes).
*/

devif_iob_send(dev, TCP_WBIOB(wrb), sndlen,
TCP_WBSENT(wrb), tcpip_hdrsize(conn));
if (dev->d_sndlen == 0)
ret = devif_iob_send(dev, TCP_WBIOB(wrb), sndlen,
TCP_WBSENT(wrb), tcpip_hdrsize(conn));
if (ret <= 0)
{
return flags;
}
Expand Down
17 changes: 11 additions & 6 deletions net/tcp/tcp_send_unbuffered.c
Expand Up @@ -126,6 +126,7 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
{
FAR struct send_s *pstate = pvpriv;
FAR struct tcp_conn_s *conn;
int ret;

DEBUGASSERT(pstate != NULL);

Expand Down Expand Up @@ -283,8 +284,12 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
* happen until the polling cycle completes).
*/

devif_send(dev, &pstate->snd_buffer[pstate->snd_acked],
sndlen, tcpip_hdrsize(conn));
ret = devif_send(dev, &pstate->snd_buffer[pstate->snd_acked],
sndlen, tcpip_hdrsize(conn));
if (ret <= 0)
{
goto end_wait;
}

/* Continue waiting */

Expand Down Expand Up @@ -365,11 +370,11 @@ static uint16_t tcpsend_eventhandler(FAR struct net_driver_s *dev,
* happen until the polling cycle completes).
*/

devif_send(dev, &pstate->snd_buffer[pstate->snd_sent],
sndlen, tcpip_hdrsize(conn));
if (dev->d_sndlen == 0)
ret = devif_send(dev, &pstate->snd_buffer[pstate->snd_sent],
sndlen, tcpip_hdrsize(conn));
if (ret <= 0)
{
return flags;
goto end_wait;
}

/* Update the amount of data sent (but not necessarily ACKed) */
Expand Down
11 changes: 7 additions & 4 deletions net/udp/udp_sendto_unbuffered.c
Expand Up @@ -194,11 +194,12 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
{
/* Copy the user data into d_appdata and send it */

devif_send(dev, pstate->st_buffer,
pstate->st_buflen, udpip_hdrsize(pstate->st_conn));
if (dev->d_sndlen == 0)
int ret = devif_send(dev, pstate->st_buffer, pstate->st_buflen,
udpip_hdrsize(pstate->st_conn));
if (ret <= 0)
{
return flags;
pstate->st_sndlen = ret;
goto end_wait;
}

#ifdef NEED_IPDOMAIN_SUPPORT
Expand All @@ -214,6 +215,8 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
pstate->st_sndlen = pstate->st_buflen;
}

end_wait:

/* Don't allow any further call backs. */

pstate->st_cb->flags = 0;
Expand Down