From 837c15dcb6e80dcd1e6beabb4b326675765a8a1e Mon Sep 17 00:00:00 2001 From: ligd Date: Mon, 16 May 2022 16:10:30 +0800 Subject: [PATCH] rpmsgfs: improve file read & write performance Signed-off-by: ligd --- fs/rpmsgfs/rpmsgfs_client.c | 111 +++++++++++++++++++++++++----------- fs/rpmsgfs/rpmsgfs_server.c | 72 ++++++++++++++++------- 2 files changed, 128 insertions(+), 55 deletions(-) diff --git a/fs/rpmsgfs/rpmsgfs_client.c b/fs/rpmsgfs/rpmsgfs_client.c index 97456ceb8ff..c79586cab6b 100644 --- a/fs/rpmsgfs/rpmsgfs_client.c +++ b/fs/rpmsgfs/rpmsgfs_client.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -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, diff --git a/fs/rpmsgfs/rpmsgfs_server.c b/fs/rpmsgfs/rpmsgfs_server.c index 6698be31bfd..a93da843354 100644 --- a/fs/rpmsgfs/rpmsgfs_server.c +++ b/fs/rpmsgfs/rpmsgfs_server.c @@ -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,