I'm pretty sure that I understand the cause.  Please apply and test
the attached patch.

Regards,
Alan
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;
        }
_______________________________________________
freebsd-stable@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to