Correct a problem in the ZERO_COPY_SOCKETS option, specifically, in
vm_page_cowfault(). Initially, if vm_page_cowfault() sleeps, the given page is wired, preventing it from being recycled. However, when transmission of the page completes, the page is unwired and returned to the page queues. At that point, the page is not in any special state that prevents it from being recycled. Consequently, vm_page_cowfault() should verify that the page is still held by the same vm object before retrying the replacement of the page. Note: The containing object is, however, safe from being recycled by virtue of having a non-zero paging-in-progress count. While I'm here, add some assertions and comments. Approved by: re (rwatson) MFC After: 3 weeks
This commit is contained in:
parent
08b755600f
commit
20dd22a24e
@ -1697,6 +1697,14 @@ vm_page_test_dirty(vm_page_t m)
|
||||
|
||||
int so_zerocp_fullpage = 0;
|
||||
|
||||
/*
|
||||
* Replace the given page with a copy. The copied page assumes
|
||||
* the portion of the given page's "wire_count" that is not the
|
||||
* responsibility of this copy-on-write mechanism.
|
||||
*
|
||||
* The object containing the given page must have a non-zero
|
||||
* paging-in-progress count and be locked.
|
||||
*/
|
||||
void
|
||||
vm_page_cowfault(vm_page_t m)
|
||||
{
|
||||
@ -1705,6 +1713,10 @@ vm_page_cowfault(vm_page_t m)
|
||||
vm_pindex_t pindex;
|
||||
|
||||
object = m->object;
|
||||
VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
|
||||
KASSERT(object->paging_in_progress != 0,
|
||||
("vm_page_cowfault: object %p's paging-in-progress count is zero.",
|
||||
object));
|
||||
pindex = m->pindex;
|
||||
|
||||
retry_alloc:
|
||||
@ -1717,8 +1729,16 @@ vm_page_cowfault(vm_page_t m)
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
VM_WAIT;
|
||||
VM_OBJECT_LOCK(object);
|
||||
vm_page_lock_queues();
|
||||
goto retry_alloc;
|
||||
if (m == vm_page_lookup(object, pindex)) {
|
||||
vm_page_lock_queues();
|
||||
goto retry_alloc;
|
||||
} else {
|
||||
/*
|
||||
* Page disappeared during the wait.
|
||||
*/
|
||||
vm_page_lock_queues();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m->cow == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user