Fix a memory leak in the device pager which is exposed by the NVIDIA
OpenGL driver. Submitted by: nvidia (possibly also tegge)
This commit is contained in:
parent
874f013517
commit
92bab635d3
@ -74,6 +74,7 @@ static uma_zone_t fakepg_zone;
|
||||
|
||||
static vm_page_t dev_pager_getfake(vm_paddr_t);
|
||||
static void dev_pager_putfake(vm_page_t);
|
||||
static void dev_pager_updatefake(vm_page_t, vm_paddr_t);
|
||||
|
||||
struct pagerops devicepagerops = {
|
||||
.pgo_init = dev_pager_init,
|
||||
@ -224,19 +225,36 @@ dev_pager_getpages(object, m, count, reqpage)
|
||||
KASSERT(ret == 0, ("dev_pager_getpage: map function returns error"));
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
/*
|
||||
* Replace the passed in reqpage page with our own fake page and
|
||||
* free up the all of the original pages.
|
||||
*/
|
||||
page = dev_pager_getfake(paddr);
|
||||
VM_OBJECT_LOCK(object);
|
||||
TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist, page, pageq);
|
||||
vm_page_lock_queues();
|
||||
for (i = 0; i < count; i++)
|
||||
vm_page_free(m[i]);
|
||||
vm_page_unlock_queues();
|
||||
vm_page_insert(page, object, offset);
|
||||
m[reqpage] = page;
|
||||
if ((m[reqpage]->flags & PG_FICTITIOUS) != 0) {
|
||||
/*
|
||||
* If the passed in reqpage page is a fake page, update it with
|
||||
* the new physical address.
|
||||
*/
|
||||
dev_pager_updatefake(m[reqpage], paddr);
|
||||
VM_OBJECT_LOCK(object);
|
||||
if (count > 1) {
|
||||
vm_page_lock_queues();
|
||||
for (i = 0; i < count; i++) {
|
||||
if (i != reqpage)
|
||||
vm_page_free(m[i]);
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Replace the passed in reqpage page with our own fake page and
|
||||
* free up the all of the original pages.
|
||||
*/
|
||||
page = dev_pager_getfake(paddr);
|
||||
VM_OBJECT_LOCK(object);
|
||||
TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist, page, pageq);
|
||||
vm_page_lock_queues();
|
||||
for (i = 0; i < count; i++)
|
||||
vm_page_free(m[i]);
|
||||
vm_page_unlock_queues();
|
||||
vm_page_insert(page, object, offset);
|
||||
m[reqpage] = page;
|
||||
}
|
||||
|
||||
return (VM_PAGER_OK);
|
||||
}
|
||||
@ -296,3 +314,13 @@ dev_pager_putfake(m)
|
||||
panic("dev_pager_putfake: bad page");
|
||||
uma_zfree(fakepg_zone, m);
|
||||
}
|
||||
|
||||
static void
|
||||
dev_pager_updatefake(m, paddr)
|
||||
vm_page_t m;
|
||||
vm_paddr_t paddr;
|
||||
{
|
||||
if (!(m->flags & PG_FICTITIOUS))
|
||||
panic("dev_pager_updatefake: bad page");
|
||||
m->phys_addr = paddr;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user