If the user does a huge I/O split the genio logging into smaller chunks
authorart <art@openbsd.org>
Tue, 18 Apr 2000 16:22:16 +0000 (16:22 +0000)
committerart <art@openbsd.org>
Tue, 18 Apr 2000 16:22:16 +0000 (16:22 +0000)
to avoid allocating a huge buffer which could lead to kmem starvation.

sys/kern/kern_ktrace.c

index 4faa4d6..7b33216 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_ktrace.c,v 1.13 2000/04/06 13:25:26 art Exp $    */
+/*     $OpenBSD: kern_ktrace.c,v 1.14 2000/04/18 16:22:16 art Exp $    */
 /*     $NetBSD: kern_ktrace.c,v 1.23 1996/02/09 18:59:36 christos Exp $        */
 
 /*
@@ -51,6 +51,8 @@
 #include <sys/mount.h>
 #include <sys/syscallargs.h>
 
+#include <vm/vm.h>
+
 struct ktr_header *ktrgetheader __P((struct proc *, int));
 int ktrops __P((struct proc *, struct proc *, int, int, struct vnode *));
 int ktrsetchildren __P((struct proc *, struct proc *, int, int,
@@ -179,33 +181,38 @@ ktrgenio(vp, fd, rw, iov, len, error)
        caddr_t cp;
        int resid = len, cnt;
        struct proc *p = curproc;       /* XXX */
-       
+       int buflen;
+
        if (error)
                return;
+
        p->p_traceflag |= KTRFAC_ACTIVE;
+
+       buflen = min(PAGE_SIZE, len + sizeof(struct ktr_genio));
+
        kth = ktrgetheader(p, KTR_GENIO);
-       MALLOC(ktp, struct ktr_genio *, sizeof(struct ktr_genio) + len,
-               M_TEMP, M_WAITOK);
+       MALLOC(ktp, struct ktr_genio *, buflen, M_TEMP, M_WAITOK);
        ktp->ktr_fd = fd;
        ktp->ktr_rw = rw;
+       kth->ktr_buf = (caddr_t)ktp;
+       kth->ktr_len = buflen;
+
        cp = (caddr_t)((char *)ktp + sizeof (struct ktr_genio));
+
+       buflen -= sizeof(struct ktr_genio);
        while (resid > 0) {
-               if ((cnt = iov->iov_len) > resid)
-                       cnt = resid;
-               if (copyin(iov->iov_base, cp, (unsigned)cnt))
+               cnt = min(iov->iov_len, buflen);
+               if (copyin(iov->iov_base, cp, cnt))
                        goto done;
-               cp += cnt;
-               resid -= cnt;
-               iov++;
+               ktrwrite(vp, kth);
+               if ((iov->iov_len -= cnt) <= 0)
+                       iov++;
        }
-       kth->ktr_buf = (caddr_t)ktp;
-       kth->ktr_len = sizeof (struct ktr_genio) + len;
-
-       ktrwrite(vp, kth);
 done:
-       FREE(kth, M_TEMP);
        FREE(ktp, M_TEMP);
+       FREE(kth, M_TEMP);
        p->p_traceflag &= ~KTRFAC_ACTIVE;
+       
 }
 
 void