From owner-freebsd-arch@FreeBSD.ORG Mon Mar 31 13:48:47 2003 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1C0D537B401; Mon, 31 Mar 2003 13:48:47 -0800 (PST) Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11]) by mx1.FreeBSD.org (Postfix) with SMTP id 57B7043FD7; Mon, 31 Mar 2003 13:48:45 -0800 (PST) (envelope-from dwmalone@maths.tcd.ie) Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP id ; 31 Mar 2003 22:48:44 +0100 (BST) To: arch@freebsd.org X-Request-Do: Date: Mon, 31 Mar 2003 22:48:44 +0100 From: David Malone Message-ID: <200303312248.aa21293@salmon.maths.tcd.ie> cc: iedowse@freebsd.org Subject: Splitting up sendit X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 31 Mar 2003 21:48:49 -0000 I wonder if anyone has any comments on this patch. It splits sendit into a part which just does the copyin of arguments and then calls a new function, kern_sendit which does the real work. The point of this is to allow the linux emulation code to avoid using the stackgap for send, sendto and sendmsg. The patch also moves the grabbing of giant into kern_sendit 'cos, as I understand it, neither copyin or the allocation of mbufs requires giant. David. Index: sys/kern/uipc_syscalls.c =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.145 diff -u -r1.145 uipc_syscalls.c --- sys/kern/uipc_syscalls.c 31 Mar 2003 06:25:42 -0000 1.145 +++ sys/kern/uipc_syscalls.c 31 Mar 2003 20:38:45 -0000 @@ -619,47 +619,18 @@ register struct msghdr *mp; int flags; { - struct uio auio; - register struct iovec *iov; - register int i; struct mbuf *control; - struct sockaddr *to = NULL; - int len, error; - struct socket *so; -#ifdef KTRACE - struct iovec *ktriov = NULL; - struct uio ktruio; - int iovlen; -#endif - - if ((error = fgetsock(td, s, &so, NULL)) != 0) - return (error); - -#ifdef MAC - error = mac_check_socket_send(td->td_ucred, so); - if (error) - goto bad; -#endif + struct sockaddr *to; + int error; - auio.uio_iov = mp->msg_iov; - auio.uio_iovcnt = mp->msg_iovlen; - auio.uio_segflg = UIO_USERSPACE; - auio.uio_rw = UIO_WRITE; - auio.uio_td = td; - auio.uio_offset = 0; /* XXX */ - auio.uio_resid = 0; - iov = mp->msg_iov; - for (i = 0; i < mp->msg_iovlen; i++, iov++) { - if ((auio.uio_resid += iov->iov_len) < 0) { - error = EINVAL; - goto bad; - } - } - if (mp->msg_name) { + if (mp->msg_name != NULL) { error = getsockaddr(&to, mp->msg_name, mp->msg_namelen); if (error) - goto bad; - } + return error; + mp->msg_name = to; + } else + to = NULL; + if (mp->msg_control) { if (mp->msg_controllen < sizeof(struct cmsghdr) #ifdef COMPAT_OLDSOCK @@ -690,7 +661,59 @@ } #endif } else { - control = 0; + control = NULL; + } + + error = kern_sendit(td, s, mp, flags, control); + +bad: + if (to) + FREE(to, M_SONAME); + return (error); +} + +int +kern_sendit(td, s, mp, flags, control) + struct thread *td; + int s; + struct msghdr *mp; + int flags; + struct mbuf *control; +{ + struct uio auio; + struct iovec *iov; + struct socket *so; + int i; + int len, error; +#ifdef KTRACE + struct iovec *ktriov = NULL; + struct uio ktruio; + int iovlen; +#endif + + mtx_lock(&Giant); + if ((error = fgetsock(td, s, &so, NULL)) != 0) + goto bad2; + +#ifdef MAC + error = mac_check_socket_send(td->td_ucred, so); + if (error) + goto bad; +#endif + + auio.uio_iov = mp->msg_iov; + auio.uio_iovcnt = mp->msg_iovlen; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_rw = UIO_WRITE; + auio.uio_td = td; + auio.uio_offset = 0; /* XXX */ + auio.uio_resid = 0; + iov = mp->msg_iov; + for (i = 0; i < mp->msg_iovlen; i++, iov++) { + if ((auio.uio_resid += iov->iov_len) < 0) { + error = EINVAL; + goto bad; + } } #ifdef KTRACE if (KTRPOINT(td, KTR_GENIO)) { @@ -701,8 +724,9 @@ } #endif len = auio.uio_resid; - error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control, - flags, td); + error = so->so_proto->pr_usrreqs->pru_sosend(so, mp->msg_name, &auio, + 0, control, flags, td); + if (error) { if (auio.uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) @@ -728,8 +752,8 @@ #endif bad: fputsock(so); - if (to) - FREE(to, M_SONAME); +bad2: + mtx_unlock(&Giant); return (error); } @@ -762,9 +786,7 @@ #endif aiov.iov_base = uap->buf; aiov.iov_len = uap->len; - mtx_lock(&Giant); error = sendit(td, uap->s, &msg, uap->flags); - mtx_unlock(&Giant); return (error); } @@ -794,9 +816,7 @@ aiov.iov_len = uap->len; msg.msg_control = 0; msg.msg_flags = 0; - mtx_lock(&Giant); error = sendit(td, uap->s, &msg, uap->flags); - mtx_unlock(&Giant); return (error); } @@ -816,7 +836,6 @@ struct iovec aiov[UIO_SMALLIOV], *iov; int error; - mtx_lock(&Giant); error = copyin(uap->msg, &msg, sizeof (struct omsghdr)); if (error) goto done2; @@ -842,7 +861,6 @@ if (iov != aiov) FREE(iov, M_IOV); done2: - mtx_unlock(&Giant); return (error); } #endif @@ -863,7 +881,6 @@ struct iovec aiov[UIO_SMALLIOV], *iov; int error; - mtx_lock(&Giant); error = copyin(uap->msg, &msg, sizeof (msg)); if (error) goto done2; @@ -891,7 +908,6 @@ if (iov != aiov) FREE(iov, M_IOV); done2: - mtx_unlock(&Giant); return (error); } Index: sys/sys/syscallsubr.h =================================================================== RCS file: /cvs/FreeBSD-CVS/src/sys/sys/syscallsubr.h,v retrieving revision 1.6 diff -u -r1.6 syscallsubr.h --- sys/sys/syscallsubr.h 3 Feb 2003 17:36:52 -0000 1.6 +++ sys/sys/syscallsubr.h 8 Feb 2003 20:47:07 -0000 @@ -32,6 +32,8 @@ #include struct sockaddr; +struct msghdr; +struct mbuf; int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen); @@ -70,6 +72,8 @@ int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg); int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, fd_set *fd_ex, struct timeval *tvp); +int kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, + struct mbuf *control); int kern_sigaction(struct thread *td, int sig, struct sigaction *act, struct sigaction *oact, int flags); int kern_sigaltstack(struct thread *td, stack_t *ss, stack_t *oss);