rpmsgfs: improve file read & write performance

Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2022-05-16 16:10:30 +08:00 committed by Petro Karashchenko
parent 344a9bc838
commit 837c15dcb6
2 changed files with 128 additions and 55 deletions

View File

@ -26,6 +26,7 @@
#include <string.h>
#include <stdio.h>
#include <sys/uio.h>
#include <nuttx/kmalloc.h>
#include <nuttx/fs/ioctl.h>
@ -48,9 +49,9 @@ struct rpmsgfs_s
struct rpmsgfs_cookie_s
{
sem_t sem;
int result;
FAR void *data;
sem_t sem;
int result;
FAR void *data;
};
/****************************************************************************
@ -148,14 +149,19 @@ static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept,
FAR struct rpmsgfs_cookie_s *cookie =
(struct rpmsgfs_cookie_s *)(uintptr_t)header->cookie;
FAR struct rpmsgfs_read_s *rsp = data;
FAR struct iovec *read = cookie->data;
cookie->result = header->result;
if (cookie->result > 0)
{
memcpy(cookie->data, rsp->buf, cookie->result);
memcpy(read->iov_base + read->iov_len, rsp->buf, cookie->result);
read->iov_len += cookie->result;
}
rpmsg_post(ept, &cookie->sem);
if (cookie->result <= 0 || read->iov_len >= rsp->count)
{
rpmsg_post(ept, &cookie->sem);
}
return 0;
}
@ -434,38 +440,60 @@ int rpmsgfs_client_close(FAR void *handle, int fd)
ssize_t rpmsgfs_client_read(FAR void *handle, int fd,
FAR void *buf, size_t count)
{
size_t read = 0;
FAR struct rpmsgfs_s *priv = handle;
struct iovec read =
{
.iov_base = buf,
.iov_len = 0,
};
struct rpmsgfs_cookie_s cookie;
struct rpmsgfs_read_s msg;
int ret = 0;
while (read < count)
memset(&cookie, 0, sizeof(cookie));
nxsem_init(&cookie.sem, 0, 0);
nxsem_set_protocol(&cookie.sem, SEM_PRIO_NONE);
cookie.data = &read;
msg.header.command = RPMSGFS_READ;
msg.header.result = -ENXIO;
msg.header.cookie = (uintptr_t)&cookie;
msg.fd = fd;
msg.count = count;
ret = rpmsg_send(&priv->ept, &msg, sizeof(msg));
if (ret < 0)
{
struct rpmsgfs_read_s msg =
{
.fd = fd,
.count = count - read,
};
ret = rpmsgfs_send_recv(handle, RPMSGFS_READ, true,
(FAR struct rpmsgfs_header_s *)&msg, sizeof(msg), buf);
if (ret <= 0)
{
break;
}
read += ret;
buf += ret;
goto out;
}
return read ? read : ret;
ret = rpmsg_wait(&priv->ept, &cookie.sem);
if (ret < 0)
{
goto out;
}
ret = cookie.result;
out:
nxsem_destroy(&cookie.sem);
return read.iov_len ? read.iov_len : ret;
}
ssize_t rpmsgfs_client_write(FAR void *handle, int fd,
FAR const void *buf, size_t count)
{
FAR struct rpmsgfs_s *priv = handle;
struct rpmsgfs_cookie_s cookie;
size_t written = 0;
int ret = 0;
memset(&cookie, 0, sizeof(cookie));
nxsem_init(&cookie.sem, 0, 0);
nxsem_set_protocol(&cookie.sem, SEM_PRIO_NONE);
while (written < count)
{
FAR struct rpmsgfs_write_s *msg;
@ -475,31 +503,46 @@ ssize_t rpmsgfs_client_write(FAR void *handle, int fd,
if (!msg)
{
ret = -ENOMEM;
break;
goto out;
}
space -= sizeof(*msg);
if (space > count - written)
if (space >= count - written)
{
space = count - written;
msg->header.cookie = (uintptr_t)&cookie;
}
else
{
msg->header.cookie = 0;
}
msg->fd = fd;
msg->count = space;
msg->header.command = RPMSGFS_WRITE;
msg->header.result = -ENXIO;
msg->fd = fd;
msg->count = space;
memcpy(msg->buf, buf + written, space);
ret = rpmsgfs_send_recv(priv, RPMSGFS_WRITE, false,
(FAR struct rpmsgfs_header_s *)msg,
sizeof(*msg) + space, NULL);
if (ret <= 0)
ret = rpmsg_send_nocopy(&priv->ept, msg, sizeof(*msg) + space);
if (ret < 0)
{
break;
goto out;
}
written += ret;
written += space;
}
return written ? written : ret;
ret = rpmsg_wait(&priv->ept, &cookie.sem);
if (ret < 0)
{
goto out;
}
ret = cookie.result;
out:
nxsem_destroy(&cookie.sem);
return ret < 0 ? ret : count;
}
off_t rpmsgfs_client_lseek(FAR void *handle, int fd,

View File

@ -370,30 +370,44 @@ static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept,
FAR struct rpmsgfs_read_s *rsp;
FAR struct file *filep;
int ret = -ENOENT;
size_t read = 0;
uint32_t space;
rsp = rpmsg_get_tx_payload_buffer(ept, &space, true);
if (!rsp)
{
return -ENOMEM;
}
*rsp = *msg;
space -= sizeof(*msg);
if (space > msg->count)
{
space = msg->count;
}
filep = rpmsgfs_get_file(priv, msg->fd);
if (filep != NULL)
while (read < msg->count)
{
ret = file_read(filep, rsp->buf, space);
rsp = rpmsg_get_tx_payload_buffer(ept, &space, true);
if (!rsp)
{
return -ENOMEM;
}
*rsp = *msg;
space -= sizeof(*msg);
if (space > msg->count - read)
{
space = msg->count - read;
}
if (filep != NULL)
{
ret = file_read(filep, rsp->buf, space);
}
rsp->header.result = ret;
rpmsg_send_nocopy(ept, rsp, (ret < 0 ? 0 : ret) + sizeof(*rsp));
if (ret <= 0)
{
break;
}
read += ret;
}
rsp->header.result = ret;
return rpmsg_send_nocopy(ept, rsp, (ret < 0 ? 0 : ret) + sizeof(*rsp));
return 0;
}
static int rpmsgfs_write_handler(FAR struct rpmsg_endpoint *ept,
@ -407,11 +421,27 @@ static int rpmsgfs_write_handler(FAR struct rpmsg_endpoint *ept,
filep = rpmsgfs_get_file(priv, msg->fd);
if (filep != NULL)
{
ret = file_write(filep, msg->buf, msg->count);
size_t written = 0;
while (written < msg->count)
{
ret = file_write(filep, msg->buf + written, msg->count - written);
if (ret < 0)
{
break;
}
written += ret;
}
}
msg->header.result = ret;
return rpmsg_send(ept, msg, sizeof(*msg));
if (msg->header.cookie != 0)
{
msg->header.result = ret;
rpmsg_send(ept, msg, sizeof(*msg));
}
return 0;
}
static int rpmsgfs_lseek_handler(FAR struct rpmsg_endpoint *ept,