From a22c590e24b49fc2f869388af1418c4c152c0566 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 24 May 2007 20:51:22 +0000 Subject: [PATCH] Add lwkt_sleep() to formalize a shortcut numerous bits of code have been using for a while, which is to directly deschedule oneself and switch away. This method of blocking requires a direct lwkt_schedule() call to reschedule the thread and is primarily used by the message port abstraction. Change the psignal code to check TDF_SINTR in the thread flags instead of checking MSGPORTF_WAITING in the thread's private message port. The lwkt_waitmsg() and lwkt_waitport() functions use the same msgport backend function (mp_waitport). Separate the backend into two functions, mp_waitport and mp_waitmsg, and allow tsleep flags to be passed in instead of flagging interruptability in the lwkt_msg flags. Optimize the lwkt_waitmsg() backends - in the fully synchronous critical path case no critical sections or spinlocks are required at all. --- sys/kern/kern_sig.c | 10 +- sys/kern/kern_synch.c | 42 +++++- sys/kern/lwkt_msgport.c | 305 +++++++++++++++++++++------------------ sys/kern/uipc_msg.c | 42 +++--- sys/kern/uipc_syscalls.c | 10 +- sys/net/netisr.c | 6 +- sys/net/route.c | 6 +- sys/netinet/if_ether.c | 4 +- sys/netinet/tcp_usrreq.c | 4 +- sys/sys/msgport.h | 21 +-- sys/sys/msgport2.h | 22 +-- sys/sys/systm.h | 3 +- 12 files changed, 268 insertions(+), 207 deletions(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 332cbfd89f..933340e341 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -37,7 +37,7 @@ * * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 * $FreeBSD: src/sys/kern/kern_sig.c,v 1.72.2.17 2003/05/16 16:34:34 obrien Exp $ - * $DragonFly: src/sys/kern/kern_sig.c,v 1.77 2007/04/29 18:25:34 dillon Exp $ + * $DragonFly: src/sys/kern/kern_sig.c,v 1.78 2007/05/24 20:51:16 dillon Exp $ */ #include "opt_ktrace.h" @@ -1210,12 +1210,16 @@ lwp_signotify(struct lwp *lp) p->p_pid, lp->lwp_tid, lp->lwp_stat, p->p_flag, lp->lwp_flag)); + /* + * To prevent a MP race with TDF_SINTR we must + * schedule the thread on the correct cpu. + */ #ifdef SMP if (td->td_gd != mycpu) lwkt_send_ipiq(td->td_gd, signotify_remote, lp); else #endif - if (td->td_msgport.mp_flags & MSGPORTF_WAITING) + if (td->td_flags & TDF_SINTR) lwkt_schedule(td); } } @@ -1238,7 +1242,7 @@ signotify_remote(void *arg) signotify(); } else { struct thread *td = lp->lwp_thread; - if (td->td_msgport.mp_flags & MSGPORTF_WAITING) + if (td->td_flags & TDF_SINTR) lwkt_schedule(td); } } diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index b4acae4b26..89783d090d 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -37,7 +37,7 @@ * * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95 * $FreeBSD: src/sys/kern/kern_synch.c,v 1.87.2.6 2002/10/13 07:29:53 kbyanc Exp $ - * $DragonFly: src/sys/kern/kern_synch.c,v 1.84 2007/05/01 00:05:18 dillon Exp $ + * $DragonFly: src/sys/kern/kern_synch.c,v 1.85 2007/05/24 20:51:16 dillon Exp $ */ #include "opt_ktrace.h" @@ -605,6 +605,46 @@ msleep(void *ident, struct spinlock *spin, int flags, return (error); } +/* + * Directly block on the LWKT thread by descheduling it. This + * is much faster then tsleep(), but the only legal way to wake + * us up is to directly schedule the thread. + * + * Setting TDF_SINTR will cause new signals to directly schedule us. + * + * This routine is typically called while in a critical section. + */ +int +lwkt_sleep(const char *wmesg, int flags) +{ + thread_t td = curthread; + int sig; + + if ((flags & PCATCH) == 0 || td->td_lwp == NULL) { + td->td_flags |= TDF_BLOCKED; + td->td_wmesg = wmesg; + lwkt_deschedule_self(td); + lwkt_switch(); + td->td_wmesg = NULL; + td->td_flags &= ~TDF_BLOCKED; + return(0); + } + if ((sig = CURSIG(td->td_lwp)) != 0) { + if (SIGISMEMBER(td->td_proc->p_sigacts->ps_sigintr, sig)) + return(EINTR); + else + return(ERESTART); + + } + td->td_flags |= TDF_BLOCKED | TDF_SINTR; + td->td_wmesg = wmesg; + lwkt_deschedule_self(td); + lwkt_switch(); + td->td_flags &= ~(TDF_BLOCKED | TDF_SINTR); + td->td_wmesg = NULL; + return(0); +} + /* * Implement the timeout for tsleep. * diff --git a/sys/kern/lwkt_msgport.c b/sys/kern/lwkt_msgport.c index d82c489fb1..ee1bbc1f6d 100644 --- a/sys/kern/lwkt_msgport.c +++ b/sys/kern/lwkt_msgport.c @@ -34,7 +34,7 @@ * NOTE! This file may be compiled for userland libraries as well as for * the kernel. * - * $DragonFly: src/sys/kern/lwkt_msgport.c,v 1.41 2007/05/24 05:51:27 dillon Exp $ + * $DragonFly: src/sys/kern/lwkt_msgport.c,v 1.42 2007/05/24 20:51:16 dillon Exp $ */ #ifdef _KERNEL @@ -129,7 +129,7 @@ lwkt_sendmsg(lwkt_port_t port, lwkt_msg_t msg) * response if the target executes the message synchronously. */ int -lwkt_domsg(lwkt_port_t port, lwkt_msg_t msg) +lwkt_domsg(lwkt_port_t port, lwkt_msg_t msg, int flags) { int error; @@ -138,7 +138,7 @@ lwkt_domsg(lwkt_port_t port, lwkt_msg_t msg) msg->ms_flags &= ~(MSGF_REPLY | MSGF_DONE); msg->ms_flags |= MSGF_SYNC; if ((error = lwkt_beginmsg(port, msg)) == EASYNC) { - error = lwkt_waitmsg(msg); + error = lwkt_waitmsg(msg, flags); } else { msg->ms_flags |= MSGF_DONE | MSGF_REPLY; } @@ -202,18 +202,21 @@ lwkt_abortmsg(lwkt_msg_t msg) static void *lwkt_thread_getport(lwkt_port_t port); static int lwkt_thread_putport(lwkt_port_t port, lwkt_msg_t msg); -static void *lwkt_thread_waitport(lwkt_port_t port, lwkt_msg_t msg); +static int lwkt_thread_waitmsg(lwkt_msg_t msg, int flags); +static void *lwkt_thread_waitport(lwkt_port_t port, int flags); static void lwkt_thread_replyport(lwkt_port_t port, lwkt_msg_t msg); static void *lwkt_spin_getport(lwkt_port_t port); static int lwkt_spin_putport(lwkt_port_t port, lwkt_msg_t msg); -static void *lwkt_spin_waitport(lwkt_port_t port, lwkt_msg_t msg); +static int lwkt_spin_waitmsg(lwkt_msg_t msg, int flags); +static void *lwkt_spin_waitport(lwkt_port_t port, int flags); static void lwkt_spin_replyport(lwkt_port_t port, lwkt_msg_t msg); static void lwkt_null_replyport(lwkt_port_t port, lwkt_msg_t msg); static void *lwkt_panic_getport(lwkt_port_t port); static int lwkt_panic_putport(lwkt_port_t port, lwkt_msg_t msg); -static void *lwkt_panic_waitport(lwkt_port_t port, lwkt_msg_t msg); +static int lwkt_panic_waitmsg(lwkt_msg_t msg, int flags); +static void *lwkt_panic_waitport(lwkt_port_t port, int flags); static void lwkt_panic_replyport(lwkt_port_t port, lwkt_msg_t msg); /* @@ -224,13 +227,15 @@ void _lwkt_initport(lwkt_port_t port, void *(*gportfn)(lwkt_port_t), int (*pportfn)(lwkt_port_t, lwkt_msg_t), - void *(*wportfn)(lwkt_port_t, lwkt_msg_t), + int (*wmsgfn)(lwkt_msg_t, int), + void *(*wportfn)(lwkt_port_t, int), void (*rportfn)(lwkt_port_t, lwkt_msg_t)) { bzero(port, sizeof(*port)); TAILQ_INIT(&port->mp_msgq); port->mp_getport = gportfn; port->mp_putport = pportfn; + port->mp_waitmsg = wmsgfn; port->mp_waitport = wportfn; port->mp_replyport = rportfn; } @@ -247,6 +252,7 @@ lwkt_initport_thread(lwkt_port_t port, thread_t td) _lwkt_initport(port, lwkt_thread_getport, lwkt_thread_putport, + lwkt_thread_waitmsg, lwkt_thread_waitport, lwkt_thread_replyport); port->mpu_td = td; @@ -265,6 +271,7 @@ lwkt_initport_spin(lwkt_port_t port) _lwkt_initport(port, lwkt_spin_getport, lwkt_spin_putport, + lwkt_spin_waitmsg, lwkt_spin_waitport, lwkt_spin_replyport); spin_init(&port->mpu_spin); @@ -280,6 +287,7 @@ lwkt_initport_replyonly_null(lwkt_port_t port) _lwkt_initport(port, lwkt_panic_getport, lwkt_panic_putport, + lwkt_panic_waitmsg, lwkt_panic_waitport, lwkt_null_replyport); } @@ -293,7 +301,8 @@ lwkt_initport_replyonly(lwkt_port_t port, void (*rportfn)(lwkt_port_t, lwkt_msg_t)) { _lwkt_initport(port, lwkt_panic_getport, lwkt_panic_putport, - lwkt_panic_waitport, rportfn); + lwkt_panic_waitmsg, lwkt_panic_waitport, + rportfn); } void @@ -301,16 +310,16 @@ lwkt_initport_putonly(lwkt_port_t port, int (*pportfn)(lwkt_port_t, lwkt_msg_t)) { _lwkt_initport(port, lwkt_panic_getport, pportfn, - lwkt_panic_waitport, lwkt_panic_replyport); + lwkt_panic_waitmsg, lwkt_panic_waitport, + lwkt_panic_replyport); } void lwkt_initport_panic(lwkt_port_t port) { _lwkt_initport(port, - lwkt_panic_getport, - lwkt_panic_putport, - lwkt_panic_waitport, + lwkt_panic_getport, lwkt_panic_putport, + lwkt_panic_waitmsg, lwkt_panic_waitport, lwkt_panic_replyport); } @@ -545,87 +554,79 @@ lwkt_thread_getport(lwkt_port_t port) } /* - * lwkt_thread_waitport() - * - * If msg is NULL, dequeue the next message from the port's message - * queue, block until a message is ready. This function never - * returns NULL. - * - * If msg is non-NULL, block until the requested message has been - * replied, then dequeue and return it. - * - * NOTE: This function should not be used to wait for specific - * incoming requests because MSGF_DONE only applies to replies. + * lwkt_thread_waitmsg() * - * Note that the API does not currently support multiple threads waiting - * on a single port. The port must be owned by the caller. + * Wait for a particular message to be replied. We must be the only + * thread waiting on the message. The port must be owned by the + * caller. */ -void * -lwkt_thread_waitport(lwkt_port_t port, lwkt_msg_t msg) +int +lwkt_thread_waitmsg(lwkt_msg_t msg, int flags) { - thread_t td = curthread; - int sentabort; - - KKASSERT(port->mpu_td == td); - crit_enter_quick(td); - if (msg == NULL) { + if ((msg->ms_flags & MSGF_DONE) == 0) { /* - * Wait for any message + * If the done bit was not set we have to block until it is. */ - if ((msg = TAILQ_FIRST(&port->mp_msgq)) == NULL) { + lwkt_port_t port = msg->ms_reply_port; + thread_t td = curthread; + int sentabort; + + KKASSERT(port->mpu_td == td); + KKASSERT(msg->ms_reply_port == port); + crit_enter_quick(td); + sentabort = 0; + + while ((msg->ms_flags & MSGF_DONE) == 0) { port->mp_flags |= MSGPORTF_WAITING; - td->td_flags |= TDF_BLOCKED; - do { - lwkt_deschedule_self(td); - lwkt_switch(); - } while ((msg = TAILQ_FIRST(&port->mp_msgq)) == NULL); - td->td_flags &= ~TDF_BLOCKED; + if (sentabort == 0) { + if ((sentabort = lwkt_sleep("waitmsg", flags)) != 0) { + lwkt_abortmsg(msg); + } + } else { + lwkt_sleep("waitabt", 0); + } port->mp_flags &= ~MSGPORTF_WAITING; } - _lwkt_pullmsg(port, msg); + if (msg->ms_flags & MSGF_QUEUED) + _lwkt_pullmsg(port, msg); + crit_exit_quick(td); } else { /* - * Wait for a specific message. + * If the done bit was set we only have to mess around with the + * message if it is queued on the reply port. */ - KKASSERT(msg->ms_reply_port == port); - if ((msg->ms_flags & MSGF_DONE) == 0) { - sentabort = 0; - while ((msg->ms_flags & MSGF_DONE) == 0) { - /* - * MSGF_PCATCH is only set by processes which wish to - * abort the message they are blocked on when a signal - * occurs. Note that we still must wait for message - * completion after sending an abort request. - */ - if (msg->ms_flags & MSGF_PCATCH) { - if (sentabort == 0 && CURSIG(port->mpu_td->td_lwp)) { - sentabort = 1; - lwkt_abortmsg(msg); - continue; - } - } + if (msg->ms_flags & MSGF_QUEUED) { + lwkt_port_t port = msg->ms_reply_port; + thread_t td = curthread; - /* - * XXX set TDF_SINTR so 'ps' knows the difference between - * an interruptable wait and a disk wait. YYY eventually - * move LWP_SINTR to TDF_SINTR to reduce duplication. - */ - port->mp_flags |= MSGPORTF_WAITING; - td->td_flags |= TDF_SINTR | TDF_BLOCKED; - lwkt_deschedule_self(td); - lwkt_switch(); - td->td_flags &= ~(TDF_SINTR | TDF_BLOCKED); - port->mp_flags &= ~MSGPORTF_WAITING; - } + KKASSERT(port->mpu_td == td); + KKASSERT(msg->ms_reply_port == port); + crit_enter_quick(td); + _lwkt_pullmsg(port, msg); + crit_exit_quick(td); } + } + return(msg->ms_error); +} - /* - * Once the MSGF_DONE bit is set, the message is stable. We - * can just check MSGF_QUEUED to determine - */ - if (msg->ms_flags & MSGF_QUEUED) - _lwkt_pullmsg(port, msg); +void * +lwkt_thread_waitport(lwkt_port_t port, int flags) +{ + thread_t td = curthread; + lwkt_msg_t msg; + int error; + + KKASSERT(port->mpu_td == td); + crit_enter_quick(td); + while ((msg = TAILQ_FIRST(&port->mp_msgq)) == NULL) { + port->mp_flags |= MSGPORTF_WAITING; + error = lwkt_sleep("waitport", flags); + port->mp_flags &= ~MSGPORTF_WAITING; + if (error) + goto done; } + _lwkt_pullmsg(port, msg); +done: crit_exit_quick(td); return(msg); } @@ -638,6 +639,13 @@ lwkt_thread_waitport(lwkt_port_t port, lwkt_msg_t msg) * thread is accessing the port. It must be used when a port is not owned * by a particular thread. This is less optimal then thread ports but * you don't have a choice if there are multiple threads accessing the port. + * + * Note on MSGPORTF_WAITING - because there may be multiple threads blocked + * on the message port, it is the responsibility of the code doing the + * wakeup to clear this flag rather then the blocked threads. Some + * superfluous wakeups may occur, which is ok. + * + * XXX synchronous message wakeups are not current optimized. */ static @@ -677,80 +685,86 @@ lwkt_spin_putport(lwkt_port_t port, lwkt_msg_t msg) } static -void * -lwkt_spin_waitport(lwkt_port_t port, lwkt_msg_t msg) +int +lwkt_spin_waitmsg(lwkt_msg_t msg, int flags) { + lwkt_port_t port; int sentabort; int error; - spin_lock_wr(&port->mpu_spin); - if (msg == NULL) { - /* - * Wait for any message - */ - while ((msg = TAILQ_FIRST(&port->mp_msgq)) == NULL) { - port->mp_flags |= MSGPORTF_WAITING; - msleep(port, &port->mpu_spin, 0, "wport", 0); - /* see note at the top on the MSGPORTF_WAITING flag */ - } - _lwkt_pullmsg(port, msg); - } else { - /* - * Wait for a specific message. - */ - KKASSERT(msg->ms_reply_port == port); - if ((msg->ms_flags & MSGF_DONE) == 0) { - sentabort = 0; - while ((msg->ms_flags & MSGF_DONE) == 0) { - void *won; - - /* - * If message was sent synchronously from the beginning - * the wakeup will be on the message structure, else it - * will be on the port structure. - */ - if (msg->ms_flags & MSGF_SYNC) { - won = msg; - } else { - won = port; - port->mp_flags |= MSGPORTF_WAITING; - } + if ((msg->ms_flags & MSGF_DONE) == 0) { + port = msg->ms_reply_port; + sentabort = 0; + spin_lock_wr(&port->mpu_spin); + while ((msg->ms_flags & MSGF_DONE) == 0) { + void *won; - /* - * MSGF_PCATCH is only set by processes which wish to - * abort the message they are blocked on when a signal - * occurs. Note that we still must wait for message - * completion after sending an abort request. - * - * XXX ERESTART not handled. - */ - if ((msg->ms_flags & MSGF_PCATCH) && sentabort == 0) { - error = msleep(won, &port->mpu_spin, PCATCH, "wmsg", 0); - if (error) { - sentabort = error; - spin_unlock_wr(&port->mpu_spin); - lwkt_abortmsg(msg); - spin_lock_wr(&port->mpu_spin); - } - } else { - error = msleep(won, &port->mpu_spin, 0, "wmsg", 0); - } - /* see note at the top on the MSGPORTF_WAITING flag */ - } /* - * Turn EINTR into ERESTART if the signal indicates. + * If message was sent synchronously from the beginning + * the wakeup will be on the message structure, else it + * will be on the port structure. */ - if (sentabort && msg->ms_error == EINTR) - msg->ms_error = sentabort; + if (msg->ms_flags & MSGF_SYNC) { + won = msg; + } else { + won = port; + port->mp_flags |= MSGPORTF_WAITING; + } /* - * Once the MSGF_DONE bit is set, the message is stable. We - * can just check MSGF_QUEUED to determine + * Only messages which support abort can be interrupted. + * We must still wait for message completion regardless. */ - if (msg->ms_flags & MSGF_QUEUED) - _lwkt_pullmsg(port, msg); + if ((flags & PCATCH) && sentabort == 0) { + error = msleep(won, &port->mpu_spin, PCATCH, "waitmsg", 0); + if (error) { + sentabort = error; + spin_unlock_wr(&port->mpu_spin); + lwkt_abortmsg(msg); + spin_lock_wr(&port->mpu_spin); + } + } else { + error = msleep(won, &port->mpu_spin, 0, "waitmsg", 0); + } + /* see note at the top on the MSGPORTF_WAITING flag */ + } + /* + * Turn EINTR into ERESTART if the signal indicates. + */ + if (sentabort && msg->ms_error == EINTR) + msg->ms_error = sentabort; + if (msg->ms_flags & MSGF_QUEUED) + _lwkt_pullmsg(port, msg); + spin_unlock_wr(&port->mpu_spin); + } else { + if (msg->ms_flags & MSGF_QUEUED) { + port = msg->ms_reply_port; + spin_lock_wr(&port->mpu_spin); + _lwkt_pullmsg(port, msg); + spin_unlock_wr(&port->mpu_spin); + } + } + return(msg->ms_error); +} + +static +void * +lwkt_spin_waitport(lwkt_port_t port, int flags) +{ + lwkt_msg_t msg; + int error; + + spin_lock_wr(&port->mpu_spin); + while ((msg = TAILQ_FIRST(&port->mp_msgq)) == NULL) { + port->mp_flags |= MSGPORTF_WAITING; + error = msleep(port, &port->mpu_spin, flags, "waitport", 0); + /* see note at the top on the MSGPORTF_WAITING flag */ + if (error) { + spin_unlock_wr(&port->mpu_spin); + return(NULL); } } + _lwkt_pullmsg(port, msg); spin_unlock_wr(&port->mpu_spin); return(msg); } @@ -820,11 +834,18 @@ lwkt_panic_putport(lwkt_port_t port, lwkt_msg_t msg) panic("lwkt_begin/do/sendmsg() illegal on port %p msg %p", port, msg); } +static +int +lwkt_panic_waitmsg(lwkt_msg_t msg, int flags) +{ + panic("port %p msg %p cannot be waited on", msg->ms_reply_port, msg); +} + static void * -lwkt_panic_waitport(lwkt_port_t port, lwkt_msg_t msg) +lwkt_panic_waitport(lwkt_port_t port, int flags) { - panic("port %p cannot be waited on msg %p", port, msg); + panic("port %p cannot be waited on", port); } static diff --git a/sys/kern/uipc_msg.c b/sys/kern/uipc_msg.c index ced607e836..36ec3a0f23 100644 --- a/sys/kern/uipc_msg.c +++ b/sys/kern/uipc_msg.c @@ -30,7 +30,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/uipc_msg.c,v 1.17 2007/05/23 08:57:05 dillon Exp $ + * $DragonFly: src/sys/kern/uipc_msg.c,v 1.18 2007/05/24 20:51:16 dillon Exp $ */ #include @@ -60,7 +60,7 @@ so_pru_abort(struct socket *so) netmsg_pru_abort); msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort; msg.nm_so = so; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -81,7 +81,7 @@ so_pru_accept(struct socket *so, struct sockaddr **nam) msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept; msg.nm_so = so; msg.nm_nam = nam; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); #endif } @@ -100,7 +100,7 @@ so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai) msg.nm_so = so; msg.nm_proto = proto; msg.nm_ai = ai; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -119,7 +119,7 @@ so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td) msg.nm_so = so; msg.nm_nam = nam; msg.nm_td = td; /* used only for prison_ip() XXX JH */ - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -137,7 +137,7 @@ so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td) msg.nm_so = so; msg.nm_nam = nam; msg.nm_td = td; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -154,7 +154,7 @@ so_pru_connect2(struct socket *so1, struct socket *so2) msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2; msg.nm_so1 = so1; msg.nm_so2 = so2; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -177,7 +177,7 @@ so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) msg.nm_data = data; msg.nm_ifp = ifp; msg.nm_td = td; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); #endif } @@ -194,7 +194,7 @@ so_pru_detach(struct socket *so) netmsg_pru_detach); msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach; msg.nm_so = so; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -210,7 +210,7 @@ so_pru_disconnect(struct socket *so) netmsg_pru_disconnect); msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect; msg.nm_so = so; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -227,7 +227,7 @@ so_pru_listen(struct socket *so, struct thread *td) msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen; msg.nm_so = so; msg.nm_td = td; /* used only for prison_ip() XXX JH */ - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -244,7 +244,7 @@ so_pru_peeraddr(struct socket *so, struct sockaddr **nam) msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr; msg.nm_so = so; msg.nm_nam = nam; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -261,7 +261,7 @@ so_pru_rcvd(struct socket *so, int flags) msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd; msg.nm_so = so; msg.nm_flags = flags; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -279,7 +279,7 @@ so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags) msg.nm_so = so; msg.nm_m = m; msg.nm_flags = flags; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -301,7 +301,7 @@ so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, msg.nm_addr = addr; msg.nm_control = control; msg.nm_td = td; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -318,7 +318,7 @@ so_pru_sense(struct socket *so, struct stat *sb) msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense; msg.nm_so = so; msg.nm_stat = sb; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -334,7 +334,7 @@ so_pru_shutdown(struct socket *so) netmsg_pru_shutdown); msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown; msg.nm_so = so; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -351,7 +351,7 @@ so_pru_sockaddr(struct socket *so, struct sockaddr **nam) msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr; msg.nm_so = so; msg.nm_nam = nam; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -370,7 +370,7 @@ so_pru_sopoll(struct socket *so, int events, struct ucred *cred) msg.nm_events = events; msg.nm_cred = cred; msg.nm_td = curthread; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); } @@ -389,7 +389,7 @@ so_pr_ctloutput(struct socket *so, struct sockopt *sopt) msg.nm_prfn = so->so_proto->pr_ctloutput; msg.nm_so = so; msg.nm_sopt = sopt; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); return (error); #endif } @@ -615,7 +615,7 @@ netmsg_so_notify_doabort(lwkt_msg_t lmsg) netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, netmsg_so_notify_abort); msg.nm_notifymsg = (void *)lmsg; - lwkt_domsg(lmsg->ms_target_port, &msg.nm_netmsg.nm_lmsg); + lwkt_domsg(lmsg->ms_target_port, &msg.nm_netmsg.nm_lmsg, 0); } } diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index a600a3f99b..d2c941d228 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -35,7 +35,7 @@ * * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 * $FreeBSD: src/sys/kern/uipc_syscalls.c,v 1.65.2.17 2003/04/04 17:11:16 tegge Exp $ - * $DragonFly: src/sys/kern/uipc_syscalls.c,v 1.81 2007/05/23 08:57:05 dillon Exp $ + * $DragonFly: src/sys/kern/uipc_syscalls.c,v 1.82 2007/05/24 20:51:16 dillon Exp $ */ #include "opt_ktrace.h" @@ -289,14 +289,14 @@ kern_accept(int s, int fflags, struct sockaddr **name, int *namelen, int *res) /* optimize for uniprocessor case later XXX JH */ port = head->so_proto->pr_mport(head, NULL, PRU_PRED); netmsg_init_abortable(&msg.nm_netmsg, &curthread->td_msgport, - MSGF_PCATCH, + 0, netmsg_so_notify, netmsg_so_notify_doabort); msg.nm_predicate = soaccept_predicate; msg.nm_fflags = fflags; msg.nm_so = head; msg.nm_etype = NM_REVENT; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, PCATCH); if (error) goto done; @@ -484,13 +484,13 @@ kern_connect(int s, int fflags, struct sockaddr *sa) port = so->so_proto->pr_mport(so, sa, PRU_PRED); netmsg_init_abortable(&msg.nm_netmsg, &curthread->td_msgport, - MSGF_PCATCH, + 0, netmsg_so_notify, netmsg_so_notify_doabort); msg.nm_predicate = soconnected_predicate; msg.nm_so = so; msg.nm_etype = NM_REVENT; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, PCATCH); } if (error == 0) { error = so->so_error; diff --git a/sys/net/netisr.c b/sys/net/netisr.c index e8d0362935..da7f82b00a 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -35,7 +35,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/net/netisr.c,v 1.32 2007/05/24 05:51:29 dillon Exp $ + * $DragonFly: src/sys/net/netisr.c,v 1.33 2007/05/24 20:51:21 dillon Exp $ */ #include @@ -135,7 +135,7 @@ netmsg_sync_putport(lwkt_port_t port, lwkt_msg_t lmsg) lmsg->ms_flags &= ~MSGF_DONE; lmsg->ms_target_port = port; /* required for abort */ netmsg->nm_dispatch(netmsg); - error = lwkt_waitmsg(lmsg); + error = lwkt_waitmsg(lmsg, 0); return(error); } @@ -222,7 +222,7 @@ netmsg_service_sync(void) netmsg_init(&smsg, &curthread->td_msgport, 0, netmsg_sync_func); TAILQ_FOREACH(reg, &netreglist, npr_entry) { - lwkt_domsg(reg->npr_port, &smsg.nm_lmsg); + lwkt_domsg(reg->npr_port, &smsg.nm_lmsg, 0); } } diff --git a/sys/net/route.c b/sys/net/route.c index 26e8b1cef5..5232166892 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -64,7 +64,7 @@ * * @(#)route.c 8.3 (Berkeley) 1/9/95 * $FreeBSD: src/sys/net/route.c,v 1.59.2.10 2003/01/17 08:04:00 ru Exp $ - * $DragonFly: src/sys/net/route.c,v 1.29 2007/05/23 08:57:10 dillon Exp $ + * $DragonFly: src/sys/net/route.c,v 1.30 2007/05/24 20:51:21 dillon Exp $ */ #include "opt_inet.h" @@ -462,7 +462,7 @@ rtredirect(struct sockaddr *dst, struct sockaddr *gateway, msg.netmask = netmask; msg.flags = flags; msg.src = src; - error = lwkt_domsg(rtable_portfn(0), &msg.netmsg.nm_lmsg); + error = lwkt_domsg(rtable_portfn(0), &msg.netmsg.nm_lmsg, 0); #else error = rtredirect_oncpu(dst, gateway, netmask, flags, src); #endif @@ -682,7 +682,7 @@ rtrequest1_global(int req, struct rt_addrinfo *rtinfo, msg.rtinfo = rtinfo; msg.callback = callback; msg.arg = arg; - error = lwkt_domsg(rtable_portfn(0), &msg.netmsg.nm_lmsg); + error = lwkt_domsg(rtable_portfn(0), &msg.netmsg.nm_lmsg, 0); #else struct rtentry *rt = NULL; diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index e785ccdf11..4c7467c7cb 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -64,7 +64,7 @@ * * @(#)if_ether.c 8.1 (Berkeley) 6/10/93 * $FreeBSD: src/sys/netinet/if_ether.c,v 1.64.2.23 2003/04/11 07:23:15 fjoe Exp $ - * $DragonFly: src/sys/netinet/if_ether.c,v 1.37 2007/05/23 08:57:09 dillon Exp $ + * $DragonFly: src/sys/netinet/if_ether.c,v 1.38 2007/05/24 20:51:22 dillon Exp $ */ /* @@ -829,7 +829,7 @@ match: msg.m = m; msg.saddr = isaddr.s_addr; msg.create = (itaddr.s_addr == myaddr.s_addr); - lwkt_domsg(rtable_portfn(0), &msg.netmsg.nm_lmsg); + lwkt_domsg(rtable_portfn(0), &msg.netmsg.nm_lmsg, 0); #endif arp_update_oncpu(m, isaddr.s_addr, (itaddr.s_addr == myaddr.s_addr), TRUE); diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 7aa9123a77..c711c7d653 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -65,7 +65,7 @@ * * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94 * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.51.2.17 2002/10/11 11:46:44 ume Exp $ - * $DragonFly: src/sys/netinet/tcp_usrreq.c,v 1.44 2007/05/24 05:51:29 dillon Exp $ + * $DragonFly: src/sys/netinet/tcp_usrreq.c,v 1.45 2007/05/24 20:51:22 dillon Exp $ */ #include "opt_ipsec.h" @@ -988,7 +988,7 @@ tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td) msg.nm_tp = tp; msg.nm_sin = sin; msg.nm_ifsin = if_sin; - error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg); + error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); } else #endif error = tcp_connect_oncpu(tp, sin, if_sin); diff --git a/sys/sys/msgport.h b/sys/sys/msgport.h index 78c75c2904..1a2958a394 100644 --- a/sys/sys/msgport.h +++ b/sys/sys/msgport.h @@ -3,7 +3,7 @@ * * Implements LWKT messages and ports. * - * $DragonFly: src/sys/sys/msgport.h,v 1.25 2007/05/24 05:51:28 dillon Exp $ + * $DragonFly: src/sys/sys/msgport.h,v 1.26 2007/05/24 20:51:19 dillon Exp $ */ #ifndef _SYS_MSGPORT_H_ @@ -88,8 +88,6 @@ typedef struct lwkt_msg { * INTRANSIT Indicates that the message state is indeterminant (e.g. * being passed through an IPI). * - * PCATCH Static flag indicates blocking entity can be interrupted. - * * ABORTABLE Static flag indicates that ms_abortfn is valid. */ #define MSGF_DONE 0x0001 /* message is complete */ @@ -97,7 +95,6 @@ typedef struct lwkt_msg { #define MSGF_QUEUED 0x0004 /* message has been queued sanitychk */ #define MSGF_SYNC 0x0008 /* synchronous message operation */ #define MSGF_INTRANSIT 0x0010 /* in-transit (IPI) */ -#define MSGF_PCATCH 0x0020 /* catch proc signal while waiting */ #define MSGF_ABORTABLE 0x0080 /* message supports abort */ #define MSG_CMD_CDEV 0x00010000 @@ -118,14 +115,11 @@ MALLOC_DECLARE(M_LWKTMSG); * - for asynch procesing should clear MSGF_DONE and set ms_target_port * to port prior to initiation of the command. * + * mp_waitmsg(): + * - wait for a particular message to be returned. + * * mp_waitport(): - * - if the passed msg is NULL we wait for, remove, and return the - * next pending message on the port. - * - if the passed msg is non-NULL we wait for that particular message, - * which typically involves waiting until MSGF_DONE is set then - * pulling the message off the port if MSGF_QUEUED is set and - * returning it. If MSGF_PCATCH is set in the message we allow - * a signal to interrupt and abort the message. + * - wait for a new message on the specified port. * * mp_replyport(): * - reply a message (executed on the originating port to return a @@ -151,7 +145,8 @@ typedef struct lwkt_port { } mp_u; void * (*mp_getport)(lwkt_port_t); int (*mp_putport)(lwkt_port_t, lwkt_msg_t); - void * (*mp_waitport)(lwkt_port_t, lwkt_msg_t); + int (*mp_waitmsg)(lwkt_msg_t, int flags); + void * (*mp_waitport)(lwkt_port_t, int flags); void (*mp_replyport)(lwkt_port_t, lwkt_msg_t); } lwkt_port; @@ -181,7 +176,7 @@ void lwkt_initport_putonly(lwkt_port_t, int (*pportfn)(lwkt_port_t, lwkt_msg_t)); void lwkt_sendmsg(lwkt_port_t, lwkt_msg_t); -int lwkt_domsg(lwkt_port_t, lwkt_msg_t); +int lwkt_domsg(lwkt_port_t, lwkt_msg_t, int); int lwkt_forwardmsg(lwkt_port_t, lwkt_msg_t); void lwkt_abortmsg(lwkt_msg_t); diff --git a/sys/sys/msgport2.h b/sys/sys/msgport2.h index d6efee89e4..3a1b278a48 100644 --- a/sys/sys/msgport2.h +++ b/sys/sys/msgport2.h @@ -3,7 +3,7 @@ * * Implements Inlines for LWKT messages and ports. * - * $DragonFly: src/sys/sys/msgport2.h,v 1.14 2007/05/24 05:51:28 dillon Exp $ + * $DragonFly: src/sys/sys/msgport2.h,v 1.15 2007/05/24 20:51:19 dillon Exp $ */ #ifndef _SYS_MSGPORT2_H_ @@ -52,14 +52,6 @@ lwkt_beginmsg(lwkt_port_t port, lwkt_msg_t msg) return(port->mp_putport(port, msg)); } -static __inline -int -lwkt_waitmsg(lwkt_msg_t msg) -{ - lwkt_port_t port = msg->ms_reply_port; - return(((lwkt_msg_t)port->mp_waitport(port, msg))->ms_error); -} - static __inline void lwkt_replymsg(lwkt_msg_t msg, int error) @@ -80,11 +72,19 @@ lwkt_getport(lwkt_port_t port) static __inline void * -lwkt_waitport(lwkt_port_t port, lwkt_msg_t msg) +lwkt_waitport(lwkt_port_t port, int flags) { - return(port->mp_waitport(port, msg)); + return(port->mp_waitport(port, flags)); } +static __inline +int +lwkt_waitmsg(lwkt_msg_t msg, int flags) +{ + return(msg->ms_reply_port->mp_waitmsg(msg, flags)); +} + + static __inline int lwkt_checkmsg(lwkt_msg_t msg) diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 436a080a40..79f5622a08 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -37,7 +37,7 @@ * * @(#)systm.h 8.7 (Berkeley) 3/29/95 * $FreeBSD: src/sys/sys/systm.h,v 1.111.2.18 2002/12/17 18:04:02 sam Exp $ - * $DragonFly: src/sys/sys/systm.h,v 1.70 2007/05/15 22:44:19 dillon Exp $ + * $DragonFly: src/sys/sys/systm.h,v 1.71 2007/05/24 20:51:19 dillon Exp $ */ #ifndef _SYS_SYSTM_H_ @@ -336,6 +336,7 @@ extern watchdog_tickle_fn wdog_tickler; int tsleep (void *, int, const char *, int); int msleep (void *, struct spinlock *, int, const char *, int); void tsleep_interlock (void *chan); +int lwkt_sleep (const char *, int); void tstop (void); void wakeup (void *chan); void wakeup_one (void *chan); -- 2.41.0