From: art Date: Fri, 3 Mar 2000 16:58:49 +0000 (+0000) Subject: If we attempted reschedule two times without suceeding, uiomove will yield, X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=f7e5f6f670fb5ad95e6af836a696534eb844dd37;p=openbsd If we attempted reschedule two times without suceeding, uiomove will yield, giving other processes a chance to run. A process feeding a huge buffer to {read,write}{,v} on a file that doesn't need to wait for I/O, could have hogged a lot of cpu in the kernel, blocking all userland activity. Based on a similiar fix in FreeBSD. --- diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c index 4a6321e1896..7c7550b9861 100644 --- a/sys/kern/kern_subr.c +++ b/sys/kern/kern_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_subr.c,v 1.10 1999/11/07 17:39:14 provos Exp $ */ +/* $OpenBSD: kern_subr.c,v 1.11 2000/03/03 16:58:49 art Exp $ */ /* $NetBSD: kern_subr.c,v 1.15 1996/04/09 17:21:56 ragge Exp $ */ /* @@ -46,6 +46,12 @@ #include #include #include +#include +#include + +void uio_yield __P((struct proc *)); + +#define UIO_NEED_YIELD (roundrobin_attempts >= 2) int uiomove(cp, n, uio) @@ -56,12 +62,15 @@ uiomove(cp, n, uio) register struct iovec *iov; u_int cnt; int error = 0; + struct proc *p; + + p = uio->uio_procp; #ifdef DIAGNOSTIC if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE) panic("uiomove: mode"); - if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc) - panic("uiomove proc"); + if (uio->uio_segflg == UIO_USERSPACE && p != curproc) + panic("uiomove: proc"); #endif while (n > 0 && uio->uio_resid) { iov = uio->uio_iov; @@ -76,6 +85,8 @@ uiomove(cp, n, uio) switch (uio->uio_segflg) { case UIO_USERSPACE: + if (UIO_NEED_YIELD) + uio_yield(p); if (uio->uio_rw == UIO_READ) error = copyout(cp, iov->iov_base, cnt); else @@ -157,6 +168,20 @@ again: return (0); } +void +uio_yield(p) + struct proc *p; +{ + int s; + + p->p_priority = p->p_usrpri; + s = splstatclock(); + setrunqueue(p); + p->p_stats->p_ru.ru_nivcsw++; + mi_switch(); + splx(s); +} + /* * General routine to allocate a hash table. */