svn commit: r256619 - projects/camlock/sys/kern
Alexander Motin
mav at FreeBSD.org
Wed Oct 16 11:30:48 UTC 2013
Author: mav
Date: Wed Oct 16 11:30:47 2013
New Revision: 256619
URL: http://svnweb.freebsd.org/changeset/base/256619
Log:
Restore BIO_UNMAPPED and BIO_TRANSIENT_MAPPING in biodonne() when unmapping
temporary mapped buffer. That fixes double unmap triggered by r256286, when
biodone() called twice for the same BIO (but with different done methods).
Move mapping removal before calling bio_done() method. I believe that it is
very wrong to do anything to BIO after reporting completion. kib@ thinks
it was done for some forgotten now case when bio_done() method needed mapped
buffer. But 1) if BIO was sent as unmapped, then IMO done() should be called
in the same way; 2) IMO there is no guatantee that buffer will be mapped at
this point at all, for example, if all underlying stack supports unmapped
I/O, so bio_done() handler can not expect that.
Modified:
projects/camlock/sys/kern/vfs_bio.c
Modified: projects/camlock/sys/kern/vfs_bio.c
==============================================================================
--- projects/camlock/sys/kern/vfs_bio.c Wed Oct 16 10:36:42 2013 (r256618)
+++ projects/camlock/sys/kern/vfs_bio.c Wed Oct 16 11:30:47 2013 (r256619)
@@ -3557,15 +3557,15 @@ biodone(struct bio *bp)
struct mtx *mtxp;
void (*done)(struct bio *);
vm_offset_t start, end;
- int transient;
if ((bp->bio_flags & BIO_TRANSIENT_MAPPING) != 0) {
+ bp->bio_flags &= ~BIO_TRANSIENT_MAPPING;
+ bp->bio_flags |= BIO_UNMAPPED;
start = trunc_page((vm_offset_t)bp->bio_data);
end = round_page((vm_offset_t)bp->bio_data + bp->bio_length);
- transient = 1;
- } else {
- transient = 0;
- start = end = 0;
+ pmap_qremove(start, OFF_TO_IDX(end - start));
+ vmem_free(transient_arena, start, end - start);
+ atomic_add_int(&inflight_transient_maps, -1);
}
done = bp->bio_done;
if (done == NULL) {
@@ -3578,11 +3578,6 @@ biodone(struct bio *bp)
bp->bio_flags |= BIO_DONE;
done(bp);
}
- if (transient) {
- pmap_qremove(start, OFF_TO_IDX(end - start));
- vmem_free(transient_arena, start, end - start);
- atomic_add_int(&inflight_transient_maps, -1);
- }
}
/*
More information about the svn-src-projects
mailing list