[Intel-gfx] [PATCH 03/37] drm/i915: Add some selftests for sg_table manipulation
Chris Wilson
chris at chris-wilson.co.uk
Thu Jan 12 11:14:42 UTC 2017
On Thu, Jan 12, 2017 at 10:56:42AM +0000, Tvrtko Ursulin wrote:
>
> On 11/01/2017 21:09, Chris Wilson wrote:
> >+static bool alloc_table(struct pfn_table *pt,
> >+ unsigned long count,
> >+ unsigned long max)
> >+{
> >+ struct scatterlist *sg;
> >+ unsigned long n, pfn;
> >+
> >+ if (sg_alloc_table(&pt->st, max,
> >+ GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN))
> >+ return false;
> >+
> >+ pt->start = PFN_BIAS;
> >+ pfn = pt->start;
> >+ sg = pt->st.sgl;
> >+ for (n = 0; n < count; n++) {
> >+ if (n)
> >+ sg = sg_next(sg);
> >+ sg_set_page(sg, pfn_to_page(pfn), (n + 1)*PAGE_SIZE, 0);
>
> For count = BIT(max_order) (== 1M) the last sg entry will have a
> size of 4GiB which would overflow sg->length, no? Especially with
> size + offset below. Unless for_each_prime_number stops below
> max_order. But where?
Stops at the last prime number less than 20, 19. A GEM_BUG_ON() would
clarify that.
>
> >+ pfn += n + 1;
>
> Please describe what kind of table and why you are building with a
> comment. If tests have no comments and do, on the first look, not
> fully obvious things, then it is a lot of effort in the future to
> work on fixes and/or maintain the code.
Creative block? If I start along those lines, I'll end up adding more
tests... Oh well.
> >+ }
> >+ sg_mark_end(sg);
> >+ pt->st.nents = n;
> >+ pt->end = pfn;
> >+
> >+ return true;
> >+}
> >+
> >+static int igt_sg_alloc(void *ignored)
> >+{
> >+ I915_SELFTEST_TIMEOUT(end_time);
> >+ const unsigned long max_order = 20; /* approximating a 4GiB object */
> >+ unsigned long prime;
> >+
> >+ for_each_prime_number(prime, max_order) {
> >+ unsigned long size = BIT(prime);
> >+ int offset;
> >+
> >+ for (offset = -1; offset <= 1; offset++) {
> >+ struct pfn_table pt;
> >+ int err;
> >+
> >+ if (!alloc_table(&pt, size + offset, size + offset))
> >+ return 0; /* out of memory, give up */
> >+
> >+ err = expect_pfn_sgtable(&pt, "sg_alloc_table");
> >+ sg_free_table(&pt.st);
> >+ if (err)
> >+ return err;
> >+
> >+ if (time_after(jiffies, end_time)) {
> >+ pr_warn("%s timed out: last table size %lu\n",
> >+ __func__, size + offset);
> >+ return 0;
> >+ }
>
> Maybe a fmt+vaarg timeout helper since I expect there'll be a lot of
> this. Like:
>
> if (i915_selftest_timeout(end_time, "fmt %s", arg))
> return 0;
>
> It is slightly tidier.
Nice.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list