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