I'm pretty sure that I understand the cause. Please apply and test
the attached patch.
Regards,
Alan
-------------- next part --------------
Index: pci/agp.c
==================================================================RCS file:
/home/ncvs/src/sys/pci/agp.c,v
retrieving revision 1.45
diff -u -r1.45 agp.c
--- pci/agp.c 16 Aug 2004 12:25:48 -0000 1.45
+++ pci/agp.c 11 Mar 2005 19:17:09 -0000
@@ -501,6 +501,7 @@
* because vm_page_grab() used with VM_ALLOC_RETRY may
* block and we can't hold a mutex while blocking.
*/
+ VM_OBJECT_LOCK(mem->am_obj);
for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
/*
* Find a page from the object and wire it
@@ -509,18 +510,18 @@
* AGP_PAGE_SIZE. If this is the first call to bind,
* the pages will be allocated and zeroed.
*/
- VM_OBJECT_LOCK(mem->am_obj);
m = vm_page_grab(mem->am_obj, OFF_TO_IDX(i),
VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
- VM_OBJECT_UNLOCK(mem->am_obj);
AGP_DPF("found page pa=%#x\n", VM_PAGE_TO_PHYS(m));
}
+ VM_OBJECT_UNLOCK(mem->am_obj);
mtx_lock(&sc->as_lock);
if (mem->am_is_bound) {
device_printf(dev, "memory already bound\n");
error = EINVAL;
+ VM_OBJECT_LOCK(mem->am_obj);
goto bad;
}
@@ -532,10 +533,9 @@
* (i.e. use alpha_XXX_dmamap()). I don't have access to any
* alpha AGP hardware to check.
*/
+ VM_OBJECT_LOCK(mem->am_obj);
for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
- VM_OBJECT_LOCK(mem->am_obj);
m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(i));
- VM_OBJECT_UNLOCK(mem->am_obj);
/*
* Install entries in the GATT, making sure that if
@@ -566,6 +566,7 @@
vm_page_wakeup(m);
vm_page_unlock_queues();
}
+ VM_OBJECT_UNLOCK(mem->am_obj);
/*
* Flush the cpu cache since we are providing a new mapping
@@ -586,7 +587,7 @@
return 0;
bad:
mtx_unlock(&sc->as_lock);
- VM_OBJECT_LOCK(mem->am_obj);
+ VM_OBJECT_LOCK_ASSERT(mem->am_obj, MA_OWNED);
for (i = 0; i < mem->am_size; i += PAGE_SIZE) {
m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(i));
vm_page_lock_queues();
Index: pci/agp_i810.c
==================================================================RCS file:
/home/ncvs/src/sys/pci/agp_i810.c,v
retrieving revision 1.30.2.1
diff -u -r1.30.2.1 agp_i810.c
--- pci/agp_i810.c 1 Mar 2005 08:11:50 -0000 1.30.2.1
+++ pci/agp_i810.c 11 Mar 2005 19:15:45 -0000
@@ -609,13 +609,10 @@
vm_page_t m;
VM_OBJECT_LOCK(mem->am_obj);
- m = vm_page_grab(mem->am_obj, 0,
+ m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY |
VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
VM_OBJECT_UNLOCK(mem->am_obj);
- vm_page_lock_queues();
mem->am_physical = VM_PAGE_TO_PHYS(m);
- vm_page_wakeup(m);
- vm_page_unlock_queues();
} else {
mem->am_physical = 0;
}