Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 03 Jul 2019 15:38:08 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 238960] panic in vm_pageout_collect_batch() when QUEUE_MACRO_DEBUG_TRASH is enabled
Message-ID:  <bug-238960-227@https.bugs.freebsd.org/bugzilla/>

index | next in thread | raw e-mail

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=238960

            Bug ID: 238960
           Summary: panic in vm_pageout_collect_batch() when
                    QUEUE_MACRO_DEBUG_TRASH is enabled
           Product: Base System
           Version: 12.0-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: dgmorris@earthlink.net

Found when working in an environment where QUEUE_MACRO_DEBUG_TRASH is enabled
by default and a system is brought to light memory pressure:

#14 0xffffffff81091654 in trap (frame=0xfffffe0031979600)
    at /usr/src/sys/amd64/amd64/trap.c:443
#15 <signal handler called>
#16 vm_pageout_collect_batch (ss=<optimized out>, dequeue=<optimized out>)
    at /usr/src/sys/vm/vm_pageout.c:283
#17 vm_pageout_next (ss=<optimized out>, dequeue=<optimized out>)
    at /usr/src/sys/vm/vm_pageout.c:315
#18 vm_pageout_scan_inactive (shortage=<optimized out>, vmd=<optimized out>, 
    addl_shortage=<optimized out>) at /usr/src/sys/vm/vm_pageout.c:1397
#19 vm_pageout_worker (arg=<optimized out>)
    at /usr/src/sys/vm/vm_pageout.c:1940
#20 0xffffffff80f10e86 in vm_pageout () at /usr/src/sys/vm/vm_pageout.c:2091

(kgdb) f 16
#16 vm_pageout_collect_batch (ss=<optimized out>, dequeue=<optimized out>)
    at /usr/src/sys/vm/vm_pageout.c:283
283         if ((m->flags & PG_MARKER) == 0) {

(kgdb) l
278 
279     vm_pagequeue_lock(pq);
280     for (m = TAILQ_NEXT(marker, plinks.q); m != NULL &&
281         ss->scanned < ss->maxscan && ss->bq.bq_cnt < VM_BATCHQUEUE_SIZE;
282         m = TAILQ_NEXT(m, plinks.q), ss->scanned++) {
283         if ((m->flags & PG_MARKER) == 0) {
284             KASSERT((m->aflags & PGA_ENQUEUED) != 0,
285                 ("page %p not enqueued", m));
286             KASSERT((m->flags & PG_FICTITIOUS) == 0,
287                 ("Fictitious page %p cannot be in page queue", m));

(kgdb) p m
$1 = (vm_page_t) 0xffffffffffffffff

The root cause is the logic for dequeue combined with the iterator of the while
loop:

                (void)vm_batchqueue_insert(&ss->bq, m);
                if (dequeue) {
                        TAILQ_REMOVE(&pq->pq_pl, m, plinks.q);
                        vm_page_aflag_clear(m, PGA_ENQUEUED);
                }

With m removed from the pagequeue TAILQ, it has no valid TAILQ_NEXT and the
DEBUG mode exposes this. Dereference of the (-1) the tailq is set to results in
panic shown.

One obvious fix would be to cache the TAILQ_NEXT() of m before dequeue and set
m to that after the dequeue [with the non-dequeue case moving the set of m out
of the loop statement]. This approach addresses the problem and removes the
panic, but others may have prettier/nicer methods.

-- 
You are receiving this mail because:
You are the assignee for the bug.

home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-238960-227>