Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern physio: deal with unaligned buffers/small maxphys/o...



details:   https://anonhg.NetBSD.org/src/rev/9f58a580d3e0
branches:  trunk
changeset: 586307:9f58a580d3e0
user:      yamt <yamt%NetBSD.org@localhost>
date:      Tue Dec 13 12:29:32 2005 +0000

description:
physio: deal with unaligned buffers/small maxphys/overlapped buffers.
fix PR/32224 from Matthias Scheler.
(uvm_vslock needs to be redesigned for threaded applications.
but it's a different problem.)

diffstat:

 sys/kern/kern_physio.c |  46 +++++++++++++++++++++++++++++++++++++---------
 1 files changed, 37 insertions(+), 9 deletions(-)

diffs (89 lines):

diff -r e14cd80fe8a6 -r 9f58a580d3e0 sys/kern/kern_physio.c
--- a/sys/kern/kern_physio.c    Tue Dec 13 10:56:16 2005 +0000
+++ b/sys/kern/kern_physio.c    Tue Dec 13 12:29:32 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_physio.c,v 1.67 2005/12/04 23:34:00 yamt Exp $    */
+/*     $NetBSD: kern_physio.c,v 1.68 2005/12/13 12:29:32 yamt Exp $    */
 
 /*-
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_physio.c,v 1.67 2005/12/04 23:34:00 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_physio.c,v 1.68 2005/12/13 12:29:32 yamt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -255,7 +255,6 @@
        int i, s;
        int error = 0;
        int error2;
-       size_t todo;
        struct buf *bp = NULL;
        struct buf *mbp;
        int concurrency = PHYSIO_CONCURRENCY - 1;
@@ -295,14 +294,19 @@
        PHOLD(l);
 
        for (i = 0; i < uio->uio_iovcnt; i++) {
+               boolean_t sync = TRUE;
+
                iovp = &uio->uio_iov[i];
                while (iovp->iov_len > 0) {
+                       size_t todo;
+
                        simple_lock(&mbp->b_interlock);
                        if ((mbp->b_flags & B_ERROR) != 0) {
                                error = mbp->b_error;
                                goto done_locked;
                        }
-                       error = physio_wait(mbp, concurrency, "physio1");
+                       error = physio_wait(mbp, sync ? 0 : concurrency,
+                           "physio1");
                        if (error) {
                                goto done_locked;
                        }
@@ -347,12 +351,36 @@
                         * for later comparison.
                         */
                        (*min_phys)(bp);
+#if defined(DIAGNOSTIC)
+                       if (bp->b_bcount > MAXPHYS)
+                               panic("todo(%zu) > MAXPHYS; minphys broken",
+                                   bp->b_bcount);
+#endif /* defined(DIAGNOSTIC) */
+
+                       sync = FALSE;
+                       if (bp->b_bcount != iovp->iov_len) {
+                               vaddr_t endp =
+                                   (vaddr_t)bp->b_data + bp->b_bcount;
+                               vaddr_t alignedendp = trunc_page(endp);
+
+                               if (alignedendp != endp) {
+                                       if (alignedendp > (vaddr_t)bp->b_data) {
+                                               bp->b_bcount = alignedendp -
+                                                   (vaddr_t)bp->b_data;
+                                       } else {
+                                               simple_lock(&mbp->b_interlock);
+                                               error = physio_wait(mbp, 0,
+                                                   "physio3");
+                                               if (error) {
+                                                       goto done_locked;
+                                               }
+                                               simple_unlock(
+                                                   &mbp->b_interlock);
+                                               sync = TRUE;
+                                       }
+                               }
+                       }
                        todo = bp->b_bufsize = bp->b_bcount;
-#if defined(DIAGNOSTIC)
-                       if (todo > MAXPHYS)
-                               panic("todo(%zu) > MAXPHYS; minphys broken",
-                                   todo);
-#endif /* defined(DIAGNOSTIC) */
 
                        /*
                         * [lock the part of the user address space involved



Home | Main Index | Thread Index | Old Index