usrsock:aggregrate more data into single recf_from response

recv request can only get maximum 1500 bytes payload in single response in
earlier design, this patch aggregrate more payloads(maximum 16k bytes)
into one response to make sure usrsock’s req/response mechanism is not
bottleneck during usrsock’s throughput test.

Signed-off-by: liangchaozhong <liangchaozhong@xiaomi.com>
This commit is contained in:
liangchaozhong 2022-11-07 10:45:44 +08:00 committed by Xiang Xiao
parent fc12542fd4
commit d6070cdfc8

View File

@ -40,6 +40,16 @@
#endif #endif
#include "usrsock_rpmsg.h" #include "usrsock_rpmsg.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define EXTRA_IOV_LEN 10
/****************************************************************************
* Private Types
****************************************************************************/
struct usrsock_rpmsg_s struct usrsock_rpmsg_s
{ {
struct file *eventfp; struct file *eventfp;
@ -65,7 +75,8 @@ static int usrsock_rpmsg_send_data_ack(struct rpmsg_endpoint *ept,
uint16_t events, uint16_t events,
uint64_t xid, int32_t result, uint64_t xid, int32_t result,
uint16_t valuelen, uint16_t valuelen,
uint16_t valuelen_nontrunc); uint16_t valuelen_nontrunc,
int32_t datalen);
static int usrsock_rpmsg_send_event(struct rpmsg_endpoint *ept, static int usrsock_rpmsg_send_event(struct rpmsg_endpoint *ept,
int16_t usockid, uint16_t events); int16_t usockid, uint16_t events);
@ -188,7 +199,8 @@ static int usrsock_rpmsg_send_data_ack(struct rpmsg_endpoint *ept,
uint16_t events, uint16_t events,
uint64_t xid, int32_t result, uint64_t xid, int32_t result,
uint16_t valuelen, uint16_t valuelen,
uint16_t valuelen_nontrunc) uint16_t valuelen_nontrunc,
int32_t datalen)
{ {
ack->reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; ack->reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK;
ack->reqack.head.flags = 0; ack->reqack.head.flags = 0;
@ -202,6 +214,7 @@ static int usrsock_rpmsg_send_data_ack(struct rpmsg_endpoint *ept,
result = 0; result = 0;
valuelen = 0; valuelen = 0;
valuelen_nontrunc = 0; valuelen_nontrunc = 0;
datalen = 0;
} }
else if (valuelen > valuelen_nontrunc) else if (valuelen > valuelen_nontrunc)
{ {
@ -211,7 +224,7 @@ static int usrsock_rpmsg_send_data_ack(struct rpmsg_endpoint *ept,
ack->valuelen = valuelen; ack->valuelen = valuelen;
ack->valuelen_nontrunc = valuelen_nontrunc; ack->valuelen_nontrunc = valuelen_nontrunc;
return rpmsg_send_nocopy(ept, ack, sizeof(*ack) + valuelen + result); return rpmsg_send_nocopy(ept, ack, sizeof(*ack) + valuelen + datalen);
} }
static int usrsock_rpmsg_send_event(struct rpmsg_endpoint *ept, static int usrsock_rpmsg_send_event(struct rpmsg_endpoint *ept,
@ -496,22 +509,28 @@ static int usrsock_rpmsg_recvfrom_handler(struct rpmsg_endpoint *ept,
size_t buflen = req->max_buflen; size_t buflen = req->max_buflen;
ssize_t ret = -EBADF; ssize_t ret = -EBADF;
uint16_t events = 0; uint16_t events = 0;
uint32_t len; uint32_t len = buflen;
int retr; int retr;
size_t totlen = 0;
struct iovec iov[EXTRA_IOV_LEN];
uint8_t i = 0;
ack = rpmsg_get_tx_payload_buffer(ept, &len, true); ack = rpmsg_get_tx_payload_buffer(ept, &len, true);
if (sizeof(*ack) + inaddrlen + buflen > len) if (sizeof(*ack) + inaddrlen + buflen < len)
{ {
buflen = len - sizeof(*ack) - inaddrlen; len = sizeof(*ack) + inaddrlen + buflen;
} }
memset(iov, 0, sizeof(iov));
if (req->usockid >= 0 && if (req->usockid >= 0 &&
req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS)
{ {
ret = psock_recvfrom(&priv->socks[req->usockid], ret = psock_recvfrom(&priv->socks[req->usockid],
(void *)(ack + 1) + inaddrlen, buflen, req->flags, (void *)(ack + 1) + inaddrlen, len - sizeof(*ack) - inaddrlen,
req->flags,
outaddrlen ? (struct sockaddr *)(ack + 1) : NULL, outaddrlen ? (struct sockaddr *)(ack + 1) : NULL,
outaddrlen ? &outaddrlen : NULL); outaddrlen ? &outaddrlen : NULL);
totlen = ret;
if (ret > 0) if (ret > 0)
{ {
if (outaddrlen < inaddrlen) if (outaddrlen < inaddrlen)
@ -520,15 +539,77 @@ static int usrsock_rpmsg_recvfrom_handler(struct rpmsg_endpoint *ept,
(void *)(ack + 1) + inaddrlen, ret); (void *)(ack + 1) + inaddrlen, ret);
} }
if (usrsock_rpmsg_available(&priv->socks[req->usockid], FIONREAD)) while (totlen < buflen && i < EXTRA_IOV_LEN)
{ {
events |= USRSOCK_EVENT_RECVFROM_AVAIL; if (!usrsock_rpmsg_available(&priv->socks[req->usockid],
FIONREAD))
{
break;
}
iov[i].iov_base = rpmsg_get_tx_payload_buffer(ept,
&len,
false);
if (!iov[i].iov_base)
{
events |= USRSOCK_EVENT_RECVFROM_AVAIL;
break;
}
if (buflen - totlen < len)
{
len = buflen - totlen;
}
/* Should never wait */
iov[i].iov_len = psock_recvfrom(
&priv->socks[req->usockid],
iov[i].iov_base, len,
req->flags | MSG_DONTWAIT,
NULL, NULL);
if ((ssize_t)iov[i].iov_len > 0)
{
totlen += iov[i].iov_len;
if (iov[i].iov_len < len)
{
break;
}
}
else
{
iov[i].iov_len = 0;
events |= USRSOCK_EVENT_RECVFROM_AVAIL;
break;
}
i++;
} }
} }
} }
retr = usrsock_rpmsg_send_data_ack(ept, retr = usrsock_rpmsg_send_data_ack(ept,
ack, events, req->head.xid, ret, inaddrlen, outaddrlen); ack, events, req->head.xid,
totlen, inaddrlen, outaddrlen,
ret);
for (i = 0; i < EXTRA_IOV_LEN; i++)
{
if (!iov[i].iov_base)
{
break;
}
if (!iov[i].iov_len || retr <= 0)
{
/* FIXME: free rpmsg buffer */
break;
}
ret = rpmsg_send_nocopy(ept,
iov[i].iov_base, iov[i].iov_len);
}
if (retr >= 0 && events == 0) if (retr >= 0 && events == 0)
{ {
pthread_mutex_lock(&priv->mutex); pthread_mutex_lock(&priv->mutex);
@ -578,7 +659,7 @@ static int usrsock_rpmsg_getsockopt_handler(struct rpmsg_endpoint *ept,
} }
return usrsock_rpmsg_send_data_ack(ept, return usrsock_rpmsg_send_data_ack(ept,
ack, 0, req->head.xid, ret, optlen, optlen); ack, 0, req->head.xid, ret, optlen, optlen, ret);
} }
static int usrsock_rpmsg_getsockname_handler(struct rpmsg_endpoint *ept, static int usrsock_rpmsg_getsockname_handler(struct rpmsg_endpoint *ept,
@ -602,7 +683,7 @@ static int usrsock_rpmsg_getsockname_handler(struct rpmsg_endpoint *ept,
} }
return usrsock_rpmsg_send_data_ack(ept, return usrsock_rpmsg_send_data_ack(ept,
ack, 0, req->head.xid, ret, inaddrlen, outaddrlen); ack, 0, req->head.xid, ret, inaddrlen, outaddrlen, ret);
} }
static int usrsock_rpmsg_getpeername_handler(struct rpmsg_endpoint *ept, static int usrsock_rpmsg_getpeername_handler(struct rpmsg_endpoint *ept,
@ -626,7 +707,7 @@ static int usrsock_rpmsg_getpeername_handler(struct rpmsg_endpoint *ept,
} }
return usrsock_rpmsg_send_data_ack(ept, return usrsock_rpmsg_send_data_ack(ept,
ack, 0, req->head.xid, ret, inaddrlen, outaddrlen); ack, 0, req->head.xid, ret, inaddrlen, outaddrlen, ret);
} }
static int usrsock_rpmsg_bind_handler(struct rpmsg_endpoint *ept, static int usrsock_rpmsg_bind_handler(struct rpmsg_endpoint *ept,
@ -732,7 +813,7 @@ static int usrsock_rpmsg_accept_handler(struct rpmsg_endpoint *ept,
} }
retr = usrsock_rpmsg_send_data_ack(ept, retr = usrsock_rpmsg_send_data_ack(ept,
ack, 0, req->head.xid, ret, inaddrlen, outaddrlen); ack, 0, req->head.xid, ret, inaddrlen, outaddrlen, ret);
if (retr >= 0 && ret >= 0) if (retr >= 0 && ret >= 0)
{ {
pthread_mutex_lock(&priv->mutex); pthread_mutex_lock(&priv->mutex);
@ -792,7 +873,7 @@ static int usrsock_rpmsg_ioctl_handler(struct rpmsg_endpoint *ept,
} }
return usrsock_rpmsg_send_data_ack(ept, return usrsock_rpmsg_send_data_ack(ept,
ack, 0, req->head.xid, ret, req->arglen, req->arglen); ack, 0, req->head.xid, ret, req->arglen, req->arglen, ret);
} }
static int usrsock_rpmsg_dns_handler(struct rpmsg_endpoint *ept, void *data, static int usrsock_rpmsg_dns_handler(struct rpmsg_endpoint *ept, void *data,