From owner-freebsd-bugs@FreeBSD.ORG Thu May 11 17:20:33 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9AB7616A695 for ; Thu, 11 May 2006 17:20:33 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8151743E47 for ; Thu, 11 May 2006 17:20:25 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k4BHKKIE043974 for ; Thu, 11 May 2006 17:20:20 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k4BHKKFJ043973; Thu, 11 May 2006 17:20:20 GMT (envelope-from gnats) Date: Thu, 11 May 2006 17:20:20 GMT Message-Id: <200605111720.k4BHKKFJ043973@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Mark Tinguely Cc: Subject: Re: kern/78179: bus_dmamem_alloc() with BUS_DMA_NOWAIT can block X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Mark Tinguely List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 May 2006 17:20:36 -0000 The following reply was made to PR kern/78179; it has been noted by GNATS. From: Mark Tinguely To: bug-followup@FreeBSD.org, PeterJeremy@optushome.com.au Cc: Subject: Re: kern/78179: bus_dmamem_alloc() with BUS_DMA_NOWAIT can block Date: Thu, 11 May 2006 11:56:06 -0500 (CDT) I stated in the -current mailing list that my original patch to sys/vm/vm_contig.c was wrong. The following is closer to what should be done. --- vm_contig.c.orig Fri Mar 10 14:30:07 2006 +++ vm_contig.c Thu May 11 11:50:14 2006 @@ -86,7 +86,7 @@ #include static int -vm_contig_launder_page(vm_page_t m) +vm_contig_launder_page(vm_page_t m, int flags) { vm_object_t object; vm_page_t m_tmp; @@ -96,6 +96,20 @@ object = m->object; if (!VM_OBJECT_TRYLOCK(object)) return (EAGAIN); + + if (flags & M_NOWAIT) { /* cannot sleep in interrupt mode */ + if ((m->flags & PG_BUSY) || m->busy) { + VM_OBJECT_UNLOCK(object); + return (EBUSY); + } else { + vm_page_test_dirty(m); + if (m->dirty) { + VM_OBJECT_UNLOCK(object); + return (EAGAIN); + } + } + } + if (vm_page_sleep_if_busy(m, TRUE, "vpctw0")) { VM_OBJECT_UNLOCK(object); vm_page_lock_queues(); @@ -138,7 +152,7 @@ } static int -vm_contig_launder(int queue) +vm_contig_launder(int queue, int flags) { vm_page_t m, next; int error; @@ -152,7 +166,7 @@ KASSERT(VM_PAGE_INQUEUE2(m, queue), ("vm_contig_launder: page %p's queue is not %d", m, queue)); - error = vm_contig_launder_page(m); + error = vm_contig_launder_page(m, flags); if (error == 0) return (TRUE); if (error == EBUSY) @@ -233,12 +247,12 @@ actmax = vm_page_queues[PQ_ACTIVE].lcnt; again1: if (inactl < inactmax && - vm_contig_launder(PQ_INACTIVE)) { + vm_contig_launder(PQ_INACTIVE, flags)) { inactl++; goto again1; } if (actl < actmax && - vm_contig_launder(PQ_ACTIVE)) { + vm_contig_launder(PQ_ACTIVE, flags)) { actl++; goto again1; } @@ -390,7 +404,7 @@ vm_page_t vm_page_alloc_contig(vm_pindex_t npages, vm_paddr_t low, vm_paddr_t high, - vm_offset_t alignment, vm_offset_t boundary) + vm_offset_t alignment, vm_offset_t boundary, int flags) { vm_object_t object; vm_offset_t size; @@ -483,7 +497,7 @@ pqtype != PQ_CACHE) { if (m->queue == PQ_ACTIVE || m->queue == PQ_INACTIVE) { - if (vm_contig_launder_page(m) != 0) + if (vm_contig_launder_page(m, flags) != 0) goto cleanup_freed; pqtype = m->queue - m->pc; if (pqtype != PQ_FREE && @@ -590,7 +604,7 @@ boundary, kernel_map); } else { pages = vm_page_alloc_contig(npgs, low, high, - alignment, boundary); + alignment, boundary, flags); if (pages == NULL) { ret = NULL; } else {