MFprojects/camlock r256619:
Restore BIO_UNMAPPED and BIO_TRANSIENT_MAPPING in biodonne() when unmapping temporary mapped buffer. That fixes double unmap if 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.
This commit is contained in:
parent
214c71f64d
commit
8160afdab1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=256830
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user