PERFORCE change 85860 for review
Alan Cox
alc at FreeBSD.org
Tue Oct 25 19:24:40 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=85860
Change 85860 by alc at 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"));
More information about the p4-projects
mailing list