Module: xenomai-3 Branch: wip/rtnet-fixes Commit: 439ee1bc1e8bfcc29a51c5d15d434b6373a4f79f URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=439ee1bc1e8bfcc29a51c5d15d434b6373a4f79f
Author: Philippe Gerum <r...@xenomai.org> Date: Tue Dec 5 11:22:59 2017 +0100 cobalt/rtdm: factor out iovec[] copy routines --- include/cobalt/kernel/rtdm/driver.h | 19 +++++++++ kernel/cobalt/rtdm/drvlib.c | 80 +++++++++++++++++++++++++++++++++++ kernel/drivers/ipc/bufp.c | 20 ++++----- kernel/drivers/ipc/iddp.c | 20 ++++----- kernel/drivers/ipc/internal.h | 19 --------- kernel/drivers/ipc/rtipc.c | 76 --------------------------------- kernel/drivers/ipc/xddp.c | 20 ++++----- 7 files changed, 129 insertions(+), 125 deletions(-) diff --git a/include/cobalt/kernel/rtdm/driver.h b/include/cobalt/kernel/rtdm/driver.h index 0c7b62e..63beb48 100644 --- a/include/cobalt/kernel/rtdm/driver.h +++ b/include/cobalt/kernel/rtdm/driver.h @@ -1339,6 +1339,25 @@ static inline int rtdm_in_rt_context(void) return (ipipe_current_domain != ipipe_root_domain); } +#define RTDM_IOV_FASTMAX 16 + +int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iov, + const struct user_msghdr *msg, + struct iovec *iov_fast); + +int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov, + const struct user_msghdr *msg, + struct iovec *iov_fast); + +static inline +void rtdm_drop_iovec(struct iovec *iov, struct iovec *iov_fast) +{ + if (iov != iov_fast) + xnfree(iov); +} + +ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen); + #endif /* !DOXYGEN_CPP */ #endif /* _COBALT_RTDM_DRIVER_H */ diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c index fb7bd7e..847e18f 100644 --- a/kernel/cobalt/rtdm/drvlib.c +++ b/kernel/cobalt/rtdm/drvlib.c @@ -30,6 +30,7 @@ #include <linux/err.h> #include <linux/anon_inodes.h> #include <rtdm/driver.h> +#include <rtdm/compat.h> #include "internal.h" #include <trace/events/cobalt-rtdm.h> @@ -2151,6 +2152,85 @@ int rtdm_ratelimit(struct rtdm_ratelimit_state *rs, const char *func) } EXPORT_SYMBOL_GPL(rtdm_ratelimit); +int rtdm_get_iovec(struct rtdm_fd *fd, struct iovec **iovp, + const struct user_msghdr *msg, + struct iovec *iov_fast) +{ + size_t len = sizeof(struct iovec) * msg->msg_iovlen; + struct iovec *iov = iov_fast; + + /* + * If the I/O vector doesn't fit in the fast memory, allocate + * a chunk from the system heap which is large enough to hold + * it. + */ + if (msg->msg_iovlen > RTDM_IOV_FASTMAX) { + iov = xnmalloc(len); + if (iov == NULL) + return -ENOMEM; + } + + *iovp = iov; + + if (!rtdm_fd_is_user(fd)) { + memcpy(iov, msg->msg_iov, len); + return 0; + } + +#ifdef CONFIG_XENO_ARCH_SYS3264 + if (rtdm_fd_is_compat(fd)) + return sys32_get_iovec(iov, + (struct compat_iovec __user *)msg->msg_iov, + msg->msg_iovlen); +#endif + + return rtdm_copy_from_user(fd, iov, msg->msg_iov, len); +} +EXPORT_SYMBOL_GPL(rtdm_get_iovec); + +int rtdm_put_iovec(struct rtdm_fd *fd, struct iovec *iov, + const struct user_msghdr *msg, + struct iovec *iov_fast) +{ + size_t len = sizeof(iov[0]) * msg->msg_iovlen; + int ret; + + if (!rtdm_fd_is_user(fd)) { + memcpy(msg->msg_iov, iov, len); + ret = 0; + } else +#ifdef CONFIG_XENO_ARCH_SYS3264 + if (rtdm_fd_is_compat(fd)) + ret = sys32_put_iovec((struct compat_iovec __user *)msg->msg_iov, + iov, msg->msg_iovlen); + else +#endif + ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len); + + if (iov != iov_fast) + xnfree(iov); + + return ret; +} +EXPORT_SYMBOL_GPL(rtdm_put_iovec); + +ssize_t rtdm_get_iov_flatlen(struct iovec *iov, int iovlen) +{ + ssize_t len; + int nvec; + + /* Return the flattened vector length. */ + for (len = 0, nvec = 0; nvec < iovlen; nvec++) { + ssize_t l = iov[nvec].iov_len; + if (l < 0 || len + l < len) /* SuS wants this. */ + return -EINVAL; + len += l; + } + + return len; +} +EXPORT_SYMBOL_GPL(rtdm_get_iov_flatlen); + #ifdef DOXYGEN_CPP /* Only used for doxygen doc generation */ /** diff --git a/kernel/drivers/ipc/bufp.c b/kernel/drivers/ipc/bufp.c index 3b565bd..e1c8672 100644 --- a/kernel/drivers/ipc/bufp.c +++ b/kernel/drivers/ipc/bufp.c @@ -307,7 +307,7 @@ static ssize_t __bufp_recvmsg(struct rtdm_fd *fd, if (!test_bit(_BUFP_BOUND, &sk->status)) return -EAGAIN; - len = rtipc_get_iov_flatlen(iov, iovlen); + len = rtdm_get_iov_flatlen(iov, iovlen); if (len == 0) return 0; /* @@ -359,7 +359,7 @@ static ssize_t __bufp_recvmsg(struct rtdm_fd *fd, static ssize_t bufp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int flags) { - struct iovec iov_fast[RTIPC_IOV_FASTMAX], *iov; + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; struct sockaddr_ipc saddr; ssize_t ret; @@ -376,18 +376,18 @@ static ssize_t bufp_recvmsg(struct rtdm_fd *fd, return -EINVAL; /* Copy I/O vector in */ - ret = rtipc_get_iovec(fd, &iov, msg, iov_fast); + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast); if (ret) return ret; ret = __bufp_recvmsg(fd, iov, msg->msg_iovlen, flags, &saddr); if (ret <= 0) { - rtipc_drop_iovec(iov, iov_fast); + rtdm_drop_iovec(iov, iov_fast); return ret; } /* Copy the updated I/O vector back */ - if (rtipc_put_iovec(fd, iov, msg, iov_fast)) + if (rtdm_put_iovec(fd, iov, msg, iov_fast)) return -EFAULT; /* Copy the source address if required. */ @@ -544,7 +544,7 @@ static ssize_t __bufp_sendmsg(struct rtdm_fd *fd, rtdm_lockctx_t s; int nvec; - len = rtipc_get_iov_flatlen(iov, iovlen); + len = rtdm_get_iov_flatlen(iov, iovlen); if (len == 0) return 0; @@ -609,7 +609,7 @@ static ssize_t bufp_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int flags) { struct rtipc_private *priv = rtdm_fd_to_private(fd); - struct iovec iov_fast[RTIPC_IOV_FASTMAX], *iov; + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; struct bufp_socket *sk = priv->state; struct sockaddr_ipc daddr; ssize_t ret; @@ -640,18 +640,18 @@ static ssize_t bufp_sendmsg(struct rtdm_fd *fd, return -EINVAL; /* Copy I/O vector in */ - ret = rtipc_get_iovec(fd, &iov, msg, iov_fast); + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast); if (ret) return ret; ret = __bufp_sendmsg(fd, iov, msg->msg_iovlen, flags, &daddr); if (ret <= 0) { - rtipc_drop_iovec(iov, iov_fast); + rtdm_drop_iovec(iov, iov_fast); return ret; } /* Copy updated I/O vector back */ - return rtipc_put_iovec(fd, iov, msg, iov_fast) ?: ret; + return rtdm_put_iovec(fd, iov, msg, iov_fast) ?: ret; } static ssize_t bufp_write(struct rtdm_fd *fd, diff --git a/kernel/drivers/ipc/iddp.c b/kernel/drivers/ipc/iddp.c index 5e2a2a1..854a4b6 100644 --- a/kernel/drivers/ipc/iddp.c +++ b/kernel/drivers/ipc/iddp.c @@ -241,7 +241,7 @@ static ssize_t __iddp_recvmsg(struct rtdm_fd *fd, if (!test_bit(_IDDP_BOUND, &sk->status)) return -EAGAIN; - maxlen = rtipc_get_iov_flatlen(iov, iovlen); + maxlen = rtdm_get_iov_flatlen(iov, iovlen); if (maxlen == 0) return 0; @@ -326,7 +326,7 @@ static ssize_t __iddp_recvmsg(struct rtdm_fd *fd, static ssize_t iddp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int flags) { - struct iovec iov_fast[RTIPC_IOV_FASTMAX], *iov; + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; struct sockaddr_ipc saddr; ssize_t ret; @@ -343,18 +343,18 @@ static ssize_t iddp_recvmsg(struct rtdm_fd *fd, return -EINVAL; /* Copy I/O vector in */ - ret = rtipc_get_iovec(fd, &iov, msg, iov_fast); + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast); if (ret) return ret; ret = __iddp_recvmsg(fd, iov, msg->msg_iovlen, flags, &saddr); if (ret <= 0) { - rtipc_drop_iovec(iov, iov_fast); + rtdm_drop_iovec(iov, iov_fast); return ret; } /* Copy the updated I/O vector back */ - if (rtipc_put_iovec(fd, iov, msg, iov_fast)) + if (rtdm_put_iovec(fd, iov, msg, iov_fast)) return -EFAULT; /* Copy the source address if required. */ @@ -387,7 +387,7 @@ static ssize_t __iddp_sendmsg(struct rtdm_fd *fd, struct xnbufd bufd; rtdm_lockctx_t s; - len = rtipc_get_iov_flatlen(iov, iovlen); + len = rtdm_get_iov_flatlen(iov, iovlen); if (len == 0) return 0; @@ -470,7 +470,7 @@ static ssize_t iddp_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int flags) { struct rtipc_private *priv = rtdm_fd_to_private(fd); - struct iovec iov_fast[RTIPC_IOV_FASTMAX], *iov; + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; struct iddp_socket *sk = priv->state; struct sockaddr_ipc daddr; ssize_t ret; @@ -501,18 +501,18 @@ static ssize_t iddp_sendmsg(struct rtdm_fd *fd, return -EINVAL; /* Copy I/O vector in */ - ret = rtipc_get_iovec(fd, &iov, msg, iov_fast); + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast); if (ret) return ret; ret = __iddp_sendmsg(fd, iov, msg->msg_iovlen, flags, &daddr); if (ret <= 0) { - rtipc_drop_iovec(iov, iov_fast); + rtdm_drop_iovec(iov, iov_fast); return ret; } /* Copy updated I/O vector back */ - return rtipc_put_iovec(fd, iov, msg, iov_fast) ?: ret; + return rtdm_put_iovec(fd, iov, msg, iov_fast) ?: ret; } static ssize_t iddp_write(struct rtdm_fd *fd, diff --git a/kernel/drivers/ipc/internal.h b/kernel/drivers/ipc/internal.h index e4614c1..7c09dd3 100644 --- a/kernel/drivers/ipc/internal.h +++ b/kernel/drivers/ipc/internal.h @@ -28,8 +28,6 @@ #include <rtdm/compat.h> #include <rtdm/driver.h> -#define RTIPC_IOV_FASTMAX 16 - struct rtipc_protocol; struct rtipc_private { @@ -85,21 +83,6 @@ static inline void rtipc_ns_to_timeval(struct timeval *tv, nanosecs_rel_t ns) tv->tv_usec = nsecs / 1000; } -int rtipc_get_iovec(struct rtdm_fd *fd, struct iovec **iov, - const struct user_msghdr *msg, - struct iovec *iov_fast); - -int rtipc_put_iovec(struct rtdm_fd *fd, struct iovec *iov, - const struct user_msghdr *msg, - struct iovec *iov_fast); - -static inline -void rtipc_drop_iovec(struct iovec *iov, struct iovec *iov_fast) -{ - if (iov != iov_fast) - xnfree(iov); -} - int rtipc_get_sockaddr(struct rtdm_fd *fd, struct sockaddr_ipc **saddrp, const void *arg); @@ -133,8 +116,6 @@ int rtipc_get_arg(struct rtdm_fd *fd, void *dst, const void *src, int rtipc_put_arg(struct rtdm_fd *fd, void *dst, const void *src, size_t len); -ssize_t rtipc_get_iov_flatlen(struct iovec *iov, int iovlen); - extern struct rtipc_protocol xddp_proto_driver; extern struct rtipc_protocol iddp_proto_driver; diff --git a/kernel/drivers/ipc/rtipc.c b/kernel/drivers/ipc/rtipc.c index b23f8d6..f236f0c 100644 --- a/kernel/drivers/ipc/rtipc.c +++ b/kernel/drivers/ipc/rtipc.c @@ -63,66 +63,6 @@ int rtipc_put_arg(struct rtdm_fd *fd, void *dst, const void *src, size_t len) return rtdm_copy_to_user(fd, dst, src, len); } -int rtipc_get_iovec(struct rtdm_fd *fd, struct iovec **iovp, - const struct user_msghdr *msg, - struct iovec *iov_fast) -{ - size_t len = sizeof(struct iovec) * msg->msg_iovlen; - struct iovec *iov = iov_fast; - - /* - * If the I/O vector doesn't fit in the fast memory, allocate - * a chunk from the system heap which is large enough to hold - * it. - */ - if (msg->msg_iovlen > RTIPC_IOV_FASTMAX) { - iov = xnmalloc(len); - if (iov == NULL) - return -ENOMEM; - } - - *iovp = iov; - - if (!rtdm_fd_is_user(fd)) { - memcpy(iov, msg->msg_iov, len); - return 0; - } - -#ifdef CONFIG_XENO_ARCH_SYS3264 - if (rtdm_fd_is_compat(fd)) - return sys32_get_iovec(iov, - (struct compat_iovec __user *)msg->msg_iov, - msg->msg_iovlen); -#endif - - return rtdm_copy_from_user(fd, iov, msg->msg_iov, len); -} - -int rtipc_put_iovec(struct rtdm_fd *fd, struct iovec *iov, - const struct user_msghdr *msg, - struct iovec *iov_fast) -{ - size_t len = sizeof(iov[0]) * msg->msg_iovlen; - int ret; - - if (!rtdm_fd_is_user(fd)) { - memcpy(msg->msg_iov, iov, len); - ret = 0; - } else -#ifdef CONFIG_XENO_ARCH_SYS3264 - if (rtdm_fd_is_compat(fd)) - ret = sys32_put_iovec((struct compat_iovec __user *)msg->msg_iov, - iov, msg->msg_iovlen); - else -#endif - ret = rtdm_copy_to_user(fd, msg->msg_iov, iov, len); - - if (iov != iov_fast) - xnfree(iov); - - return ret; -} - int rtipc_get_sockaddr(struct rtdm_fd *fd, struct sockaddr_ipc **saddrp, const void *arg) { @@ -397,22 +337,6 @@ int rtipc_get_length(struct rtdm_fd *fd, size_t *lenp, return rtdm_safe_copy_from_user(fd, lenp, arg, sizeof(*lenp)); } -ssize_t rtipc_get_iov_flatlen(struct iovec *iov, int iovlen) -{ - ssize_t len; - int nvec; - - /* Return the flattened vector length. */ - for (len = 0, nvec = 0; nvec < iovlen; nvec++) { - ssize_t l = iov[nvec].iov_len; - if (l < 0 || len + l < len) /* SuS wants this. */ - return -EINVAL; - len += l; - } - - return len; -} - static int rtipc_socket(struct rtdm_fd *fd, int protocol) { struct rtipc_protocol *proto; diff --git a/kernel/drivers/ipc/xddp.c b/kernel/drivers/ipc/xddp.c index 4d43cfa..95bee57 100644 --- a/kernel/drivers/ipc/xddp.c +++ b/kernel/drivers/ipc/xddp.c @@ -282,7 +282,7 @@ static ssize_t __xddp_recvmsg(struct rtdm_fd *fd, if (!test_bit(_XDDP_BOUND, &sk->status)) return -EAGAIN; - maxlen = rtipc_get_iov_flatlen(iov, iovlen); + maxlen = rtdm_get_iov_flatlen(iov, iovlen); if (maxlen == 0) return 0; @@ -337,7 +337,7 @@ out: static ssize_t xddp_recvmsg(struct rtdm_fd *fd, struct user_msghdr *msg, int flags) { - struct iovec iov_fast[RTIPC_IOV_FASTMAX], *iov; + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; struct sockaddr_ipc saddr; ssize_t ret; @@ -354,18 +354,18 @@ static ssize_t xddp_recvmsg(struct rtdm_fd *fd, return -EINVAL; /* Copy I/O vector in */ - ret = rtipc_get_iovec(fd, &iov, msg, iov_fast); + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast); if (ret) return ret; ret = __xddp_recvmsg(fd, iov, msg->msg_iovlen, flags, &saddr); if (ret <= 0) { - rtipc_drop_iovec(iov, iov_fast); + rtdm_drop_iovec(iov, iov_fast); return ret; } /* Copy the updated I/O vector back */ - if (rtipc_put_iovec(fd, iov, msg, iov_fast)) + if (rtdm_put_iovec(fd, iov, msg, iov_fast)) return -EFAULT; /* Copy the source address if required. */ @@ -473,7 +473,7 @@ static ssize_t __xddp_sendmsg(struct rtdm_fd *fd, struct xnbufd bufd; rtdm_lockctx_t s; - len = rtipc_get_iov_flatlen(iov, iovlen); + len = rtdm_get_iov_flatlen(iov, iovlen); if (len == 0) return 0; @@ -593,7 +593,7 @@ static ssize_t xddp_sendmsg(struct rtdm_fd *fd, const struct user_msghdr *msg, int flags) { struct rtipc_private *priv = rtdm_fd_to_private(fd); - struct iovec iov_fast[RTIPC_IOV_FASTMAX], *iov; + struct iovec iov_fast[RTDM_IOV_FASTMAX], *iov; struct xddp_socket *sk = priv->state; struct sockaddr_ipc daddr; ssize_t ret; @@ -636,18 +636,18 @@ static ssize_t xddp_sendmsg(struct rtdm_fd *fd, return -EINVAL; /* Copy I/O vector in */ - ret = rtipc_get_iovec(fd, &iov, msg, iov_fast); + ret = rtdm_get_iovec(fd, &iov, msg, iov_fast); if (ret) return ret; ret = __xddp_sendmsg(fd, iov, msg->msg_iovlen, flags, &daddr); if (ret <= 0) { - rtipc_drop_iovec(iov, iov_fast); + rtdm_drop_iovec(iov, iov_fast); return ret; } /* Copy updated I/O vector back */ - return rtipc_put_iovec(fd, iov, msg, iov_fast) ?: ret; + return rtdm_put_iovec(fd, iov, msg, iov_fast) ?: ret; } static ssize_t xddp_write(struct rtdm_fd *fd, _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git