On Wed, May 18, 2011 at 06:48:02PM +0200, Ariane van der Steldt wrote: > Pmemrange being a difficult algorithm and reports of dma controllers > being unhappy with what it serves up, plus some prodding from theo, > caused me to write this little validation step. > > Very low overhead, but guaranteed to catch bugs when they happen, > instead of when finally a dma controller does its own validation. > > Ok?
I'd still like an ok for this diff. I added one fix (as comment) below. > Index: uvm_pmemrange.c > =================================================================== > RCS file: /cvs/src/sys/uvm/uvm_pmemrange.c,v > retrieving revision 1.22 > diff -u -d -p -r1.22 uvm_pmemrange.c > --- uvm_pmemrange.c 6 Apr 2011 12:31:10 -0000 1.22 > +++ uvm_pmemrange.c 18 May 2011 16:42:36 -0000 > @@ -746,6 +746,9 @@ uvm_pmr_getpages(psize_t count, paddr_t > int memtype; /* Requested memtype. */ > int memtype_init; /* Best memtype. */ > int desperate; /* True if allocation failed. */ > +#ifdef DIAGNOSTIC > + struct vm_page *diag_prev; /* Used during validation. */ > +#endif /* DIAGNOSTIC */ > > /* > * Validate arguments. > @@ -1048,6 +1051,11 @@ out: > uvm_unlock_fpageq(); > > /* Update statistics and zero pages if UVM_PLA_ZERO. */ > +#ifdef DIAGNOSTIC > + fnsegs = 0; > + fcount = 0; > + diag_prev = NULL; > +#endif /* DIAGNOSTIC */ > TAILQ_FOREACH(found, result, pageq) { > atomic_clearbits_int(&found->pg_flags, > PG_PMAP0|PG_PMAP1|PG_PMAP2|PG_PMAP3); > @@ -1074,7 +1082,36 @@ out: > */ > KDASSERT(start == 0 || atop(VM_PAGE_TO_PHYS(found)) >= start); > KDASSERT(end == 0 || atop(VM_PAGE_TO_PHYS(found)) < end); > + > +#ifdef DIAGNOSTIC > + /* > + * Update fcount (# found pages) and > + * fnsegs (# found segments) counters. > + */ > + if (diag_prev == NULL || > + /* new segment if it contains a hole */ > + atop(VM_PAGE_TO_PHYS(diag_prev)) + 1 != > + atop(VM_PAGE_TO_PHYS(found)) || > + /* new segment if it crosses boundary */ > + (atop(VM_PAGE_TO_PHYS(diag_prev)) & ~(boundary - 1)) != > + (atop(VM_PAGE_TO_PHYS(found)) & ~(boundary - 1))) > + fnsegs++; > + fcount++; > + > + diag_prev = found; > +#endif /* DIAGNOSTIC */ > } > + > +#ifdef DIAGNOSTIC > + /* > + * Panic on algorithm failure. > + */ > + if (fcount > count || fnsegs > maxseg) That should be fcount != count ofcourse. > + panic("pmemrange allocation error: " > + "allocated %ld pages in %d segments, " > + "but request was %ld pages in %d segments", > + fcount, fnsegs, count, maxseg); > +#endif /* DIAGNOSTIC */ > > return 0; > } > -- Ariane