summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_subr.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1999-02-02 12:11:01 +0000
committerbde <bde@FreeBSD.org>1999-02-02 12:11:01 +0000
commit0fd52730c216aa70c9761b100b73f0ec0ffab6ea (patch)
treec5b556662a4b50e4b3fc67821a352652ee54717e /sys/kern/kern_subr.c
parentd8bfa57b5f8f231ac6d1d644df6f6b801593952a (diff)
downloadFreeBSD-src-0fd52730c216aa70c9761b100b73f0ec0ffab6ea.zip
FreeBSD-src-0fd52730c216aa70c9761b100b73f0ec0ffab6ea.tar.gz
Switch context before doing some i/o operations that might block if
context would be switched on return to user mode. This fixes some denial of service problems.
Diffstat (limited to 'sys/kern/kern_subr.c')
-rw-r--r--sys/kern/kern_subr.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c
index a96d554..d8e1f08 100644
--- a/sys/kern/kern_subr.c
+++ b/sys/kern/kern_subr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
- * $Id: kern_subr.c,v 1.23 1999/01/08 17:31:10 eivind Exp $
+ * $Id: kern_subr.c,v 1.24 1999/01/10 01:58:24 eivind Exp $
*/
#include <sys/param.h>
@@ -44,6 +44,7 @@
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/lock.h>
+#include <sys/resourcevar.h>
#include <sys/vnode.h>
#include <vm/vm.h>
@@ -51,6 +52,10 @@
#include <vm/vm_page.h>
#include <vm/vm_map.h>
+#include <machine/cpu.h>
+
+static void uio_yield __P((void));
+
int
uiomove(cp, n, uio)
register caddr_t cp;
@@ -81,6 +86,8 @@ uiomove(cp, n, uio)
case UIO_USERSPACE:
case UIO_USERISPACE:
+ if (resched_wanted())
+ uio_yield();
if (uio->uio_rw == UIO_READ)
error = copyout(cp, iov->iov_base, cnt);
else
@@ -139,6 +146,8 @@ uiomoveco(cp, n, uio, obj)
case UIO_USERSPACE:
case UIO_USERISPACE:
+ if (resched_wanted())
+ uio_yield();
if (uio->uio_rw == UIO_READ) {
if (vfs_ioopt && ((cnt & PAGE_MASK) == 0) &&
((((intptr_t) iov->iov_base) & PAGE_MASK) == 0) &&
@@ -214,6 +223,8 @@ uioread(n, uio, obj, nread)
cnt &= ~PAGE_MASK;
+ if (resched_wanted())
+ uio_yield();
error = vm_uiomove(&curproc->p_vmspace->vm_map, obj,
uio->uio_offset, cnt,
(vm_offset_t) iov->iov_base, &npagesmoved);
@@ -389,3 +400,17 @@ phashinit(elements, type, nentries)
*nentries = hashsize;
return (hashtbl);
}
+
+static void
+uio_yield()
+{
+ struct proc *p;
+ int s;
+
+ p = curproc;
+ s = splhigh();
+ setrunqueue(p);
+ p->p_stats->p_ru.ru_nivcsw++;
+ mi_switch();
+ splx(s);
+}
OpenPOWER on IntegriCloud