Date: Wed, 26 Oct 2005 02:24:39 GMT From: Alan Cox <alc@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 85860 for review Message-ID: <200510260224.j9Q2Odds040190@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=85860 Change 85860 by alc@alc_sp01 on 2005/10/26 02:24:09 Properly synchronize the preemption of reservations. Affected files ... .. //depot/projects/superpages/src/sys/vm/vm_reserve.c#8 edit Differences ... ==== //depot/projects/superpages/src/sys/vm/vm_reserve.c#8 (text+ko) ==== @@ -512,8 +512,10 @@ preempt_contig_alloc(int *level, int free_pool) { int l, lev = level ? *level : -1; + vm_object_t object; vm_page_t m = NULL; - reservation_t sp; + reservation_t sp, sp_next; + boolean_t was_trylocked; retry: if (free_pool) { @@ -531,13 +533,26 @@ /* 3. try rres at level lev or higher */ for (l = lev; l <= SP_LEVELS - 2; l++) { - while ( (sp = TAILQ_FIRST(&rres[l])) ) { + mtx_lock(&rres_mtx); + TAILQ_FOREACH_SAFE(sp, &rres[l], next, sp_next) { KASSERT(sp->rql==l && sp->rql<sp->level,("preempt_contig_alloc: rql invalid")); - preempt(sp, lev, NULL); - m = buddy_alloc(SP_ORDER(lev), FALSE); - if (m != NULL) - goto done; + object = sp->object; + was_trylocked = VM_OBJECT_TRYLOCK(object); + if (was_trylocked || VM_OBJECT_LOCKED(object)) { + TAILQ_REMOVE(&rres[l], sp, next); + mtx_unlock(&rres_mtx); + sp->rql = NO_RESQ; + preempt(sp, lev, NULL); + if (was_trylocked) + VM_OBJECT_UNLOCK(object); + m = buddy_alloc(SP_ORDER(lev), FALSE); + if (m != NULL) + goto done; + mtx_lock(&rres_mtx); + sp_next = TAILQ_FIRST(&rres[l]); + } } + mtx_unlock(&rres_mtx); } /* Downgrade level, retry free, rres... */ @@ -552,13 +567,26 @@ } /* 5, 7, 9... */ - while ( (sp = TAILQ_FIRST(&rres[lev])) ) { + mtx_lock(&rres_mtx); + TAILQ_FOREACH_SAFE(sp, &rres[lev], next, sp_next) { KASSERT(sp->rql==lev && sp->rql<sp->level,("preempt_alloc_contig")); - preempt(sp, lev, NULL); - m = buddy_alloc(SP_ORDER(lev), FALSE); - if (m != NULL) - goto done; + object = sp->object; + was_trylocked = VM_OBJECT_TRYLOCK(object); + if (was_trylocked || VM_OBJECT_LOCKED(object)) { + TAILQ_REMOVE(&rres[lev], sp, next); + mtx_unlock(&rres_mtx); + sp->rql = NO_RESQ; + preempt(sp, lev, NULL); + if (was_trylocked) + VM_OBJECT_UNLOCK(object); + m = buddy_alloc(SP_ORDER(lev), FALSE); + if (m != NULL) + goto done; + mtx_lock(&rres_mtx); + sp_next = TAILQ_FIRST(&rres[lev]); + } } + mtx_unlock(&rres_mtx); } done: KASSERT(*level>= -1,("preempt_alloc_contig"));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200510260224.j9Q2Odds040190>