Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_bio.c
Show First 20 Lines • Show All 5,148 Lines • ▼ Show 20 Lines | vfs_bio_getpages(struct vnode *vp, vm_page_t *ma, int count, | ||||
if (rahead != NULL) | if (rahead != NULL) | ||||
*rahead = pgsin_a; | *rahead = pgsin_a; | ||||
VM_CNT_INC(v_vnodein); | VM_CNT_INC(v_vnodein); | ||||
VM_CNT_ADD(v_vnodepgsin, pgsin); | VM_CNT_ADD(v_vnodepgsin, pgsin); | ||||
br_flags = (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMAPPED_BUFS) | br_flags = (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMAPPED_BUFS) | ||||
!= 0) ? GB_UNMAPPED : 0; | != 0) ? GB_UNMAPPED : 0; | ||||
again: | again: | ||||
for (i = 0; i < count; i++) | for (i = 0; i < count; i++) { | ||||
if (ma[i] != bogus_page) | |||||
vm_page_busy_downgrade(ma[i]); | vm_page_busy_downgrade(ma[i]); | ||||
} | |||||
lbnp = -1; | lbnp = -1; | ||||
for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
m = ma[i]; | m = ma[i]; | ||||
if (m == bogus_page) | |||||
continue; | |||||
/* | /* | ||||
* Pages are shared busy and the object lock is not | * Pages are shared busy and the object lock is not | ||||
* owned, which together allow for the pages' | * owned, which together allow for the pages' | ||||
* invalidation. The racy test for validity avoids | * invalidation. The racy test for validity avoids | ||||
* useless creation of the buffer for the most typical | * useless creation of the buffer for the most typical | ||||
* case when invalidation is not used in redo or for | * case when invalidation is not used in redo or for | ||||
* parallel read. The shared->excl upgrade loop at | * parallel read. The shared->excl upgrade loop at | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | if (i == count - 1 && lpart) { | ||||
vm_page_zero_invalid(m, TRUE); | vm_page_zero_invalid(m, TRUE); | ||||
} | } | ||||
next_page:; | next_page:; | ||||
} | } | ||||
end_pages: | end_pages: | ||||
redo = false; | redo = false; | ||||
for (i = 0; i < count; i++) { | for (i = 0; i < count; i++) { | ||||
if (ma[i] == bogus_page) | |||||
continue; | |||||
markj: Could this fix PR 242626, where we saw an infinite loop in vfs_bio_getpages()? | |||||
Done Inline ActionsYes, I suspect it is the same cause as 244713. But both bogus page skipping, and unbusying nearby pages from the same buffer are needed. kib: Yes, I suspect it is the same cause as 244713. But both bogus page skipping, and unbusying… | |||||
if (vm_page_busy_tryupgrade(ma[i]) == 0) { | if (vm_page_busy_tryupgrade(ma[i]) == 0) { | ||||
vm_page_sunbusy(ma[i]); | vm_page_sunbusy(ma[i]); | ||||
ma[i] = vm_page_grab_unlocked(object, ma[i]->pindex, | ma[i] = vm_page_grab_unlocked(object, ma[i]->pindex, | ||||
VM_ALLOC_NORMAL); | VM_ALLOC_NORMAL); | ||||
} | } | ||||
/* | /* | ||||
* Since the pages were only sbusy while neither the | * Since the pages were only sbusy while neither the | ||||
▲ Show 20 Lines • Show All 210 Lines • Show Last 20 Lines |
Could this fix PR 242626, where we saw an infinite loop in vfs_bio_getpages()?