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