From owner-freebsd-current@freebsd.org Wed Dec 28 23:59:20 2016 Return-Path: Delivered-To: freebsd-current@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 41D7CC95B54 for ; Wed, 28 Dec 2016 23:59:20 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D470B1059 for ; Wed, 28 Dec 2016 23:59:19 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from tom.home (kib@localhost [127.0.0.1]) by kib.kiev.ua (8.15.2/8.15.2) with ESMTPS id uBSNxDQL099549 (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO); Thu, 29 Dec 2016 01:59:13 +0200 (EET) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.10.3 kib.kiev.ua uBSNxDQL099549 Received: (from kostik@localhost) by tom.home (8.15.2/8.15.2/Submit) id uBSNxCAs099548; Thu, 29 Dec 2016 01:59:12 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Thu, 29 Dec 2016 01:59:12 +0200 From: Konstantin Belousov To: Steve Kargl Cc: freebsd-current@freebsd.org Subject: Re: unkillable firefox Message-ID: <20161228235912.GE1923@kib.kiev.ua> References: <20161220212920.GA69662@troutmask.apl.washington.edu> <20161228205453.GA96328@troutmask.apl.washington.edu> <20161228222836.GD1923@kib.kiev.ua> <20161228232439.GA1031@troutmask.apl.washington.edu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20161228232439.GA1031@troutmask.apl.washington.edu> User-Agent: Mutt/1.7.2 (2016-11-26) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on tom.home X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Dec 2016 23:59:20 -0000 On Wed, Dec 28, 2016 at 03:24:39PM -0800, Steve Kargl wrote: > Patch results in a panic when I start X server. > > Fatal trap 12: page fault while in kernel mode > cpuid = 7; apic id = 17 > fault virtual address = 0x30 > fault code = supervisor read data, page not present > instruction pointer = 0x20:0xffffffff807d3999 > stack pointer = 0x0:0xfffffe0238c22720 > frame pointer = 0x0:0xfffffe0238c22750 > code segment = base 0x0, limit 0xfffff, type 0x1b > = DPL 0, pres 1, long 1, def32 0, gran 1 > processor eflags = interrupt enabled, resume, IOPL = 0 > current process = 790 (fvwm) > trap number = 12 > panic: page fault > cpuid = 7 > KDB: stack backtrace: > db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0238c223b0 > vpanic() at vpanic+0x186/frame 0xfffffe0238c22430 > panic() at panic+0x43/frame 0xfffffe0238c22490 > trap_fatal() at trap_fatal+0x322/frame 0xfffffe0238c224e0 > trap_pfault() at trap_pfault+0x1bc/frame 0xfffffe0238c22540 > trap() at trap+0x253/frame 0xfffffe0238c22650 > calltrap() at calltrap+0x8/frame 0xfffffe0238c22650 > --- trap 0xc, rip = 0xffffffff807d3999, rsp = 0xfffffe0238c22720, rbp = 0xfffffe0238c22750 --- > vm_fault_populate_cleanup() at vm_fault_populate_cleanup+0x39/frame 0xfffffe0238c22750 > vm_fault_hold() at vm_fault_hold+0x1a65/frame 0xfffffe0238c22880 > vm_fault() at vm_fault+0x78/frame 0xfffffe0238c228c0 > trap_pfault() at trap_pfault+0xf6/frame 0xfffffe0238c22920 > trap() at trap+0x2ed/frame 0xfffffe0238c22a30 > calltrap() at calltrap+0x8/frame 0xfffffe0238c22a30 > > (kgdb) bt > #0 doadump (textdump=1) at pcpu.h:222 > #1 0xffffffff80590002 in kern_reboot (howto=) > at /usr/src/sys/kern/kern_shutdown.c:386 > #2 0xffffffff805904c0 in vpanic (fmt=, > ap=) at /usr/src/sys/kern/kern_shutdown.c:779 > #3 0xffffffff805902f3 in panic (fmt=) > at /usr/src/sys/kern/kern_shutdown.c:710 > #4 0xffffffff808151d2 in trap_fatal (frame=0xfffffe0238c22660, eva=48) > at /usr/src/sys/amd64/amd64/trap.c:801 > #5 0xffffffff8081539c in trap_pfault (frame=0xfffffe0238c22660, usermode=0) > at /usr/src/sys/amd64/amd64/trap.c:658 > #6 0xffffffff80814ab3 in trap (frame=0xfffffe0238c22660) > at /usr/src/sys/amd64/amd64/trap.c:421 > #7 0xffffffff807fb023 in calltrap () > at /usr/src/sys/amd64/amd64/exception.S:236 > #8 0xffffffff807d3999 in vm_fault_populate_cleanup ( > object=, first=, > last=) at pcpu.h:222 > #9 0xffffffff807d2105 in vm_fault_hold (map=0xfffff8000999f000, > vaddr=8597401600, fault_type=, fault_flags=0, > m_hold=0x0) at /usr/src/sys/vm/vm_fault.c:402 > #10 0xffffffff807d0658 in vm_fault (map=0xfffff8000999f000, > vaddr=, fault_type=1 '\001', > fault_flags=) at /usr/src/sys/vm/vm_fault.c:464 > #11 0xffffffff808152d6 in trap_pfault (frame=0xfffffe0238c22a40, usermode=1) > at /usr/src/sys/amd64/amd64/trap.c:708 > #12 0xffffffff80814b4d in trap (frame=0xfffffe0238c22a40) > at /usr/src/sys/amd64/amd64/trap.c:326 > #13 0xffffffff807fb023 in calltrap () > at /usr/src/sys/amd64/amd64/exception.S:236 > #14 0x0000000200b25c33 in ?? () > You do not have INVARIANTS in the kernel config ? Below is my guess about the issue in the patch. Hopefully it fixes your panic and still cure the bug I see in your previous report. diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index e8fb5d00408..4d25e127e8d 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -304,13 +304,48 @@ vm_fault_restore_map_lock(struct faultstate *fs) fs->lookup_still_valid = true; } +static void +vm_fault_populate_check_page(vm_page_t m, vm_object_t object, vm_pindex_t pidx) +{ + + /* + * Check each page to ensure that the driver is + * obeying the interface: the page must be installed + * in the object, fully valid, and exclusively busied. + */ + MPASS(m != NULL); + MPASS(vm_page_xbusied(m)); + MPASS(m->valid == VM_PAGE_BITS_ALL); + MPASS(m->object == object); + MPASS(m->pindex == pidx); +} + +static void +vm_fault_populate_cleanup(vm_object_t object, vm_pindex_t first, + vm_pindex_t last) +{ + vm_page_t m; + vm_pindex_t pidx; + + VM_OBJECT_ASSERT_WLOCKED(object); + if (first > last) /* micro-op: avoid page lookup */ + return; + for (pidx = first, m = vm_page_lookup(object, pidx); + pidx <= last; pidx++, m = vm_page_next(m)) { + vm_fault_populate_check_page(m, object, pidx); + vm_page_lock(m); + vm_page_activate(m); + vm_page_unlock(m); + vm_page_xunbusy(m); + } +} static int vm_fault_populate(struct faultstate *fs, vm_offset_t vaddr, vm_prot_t prot, int fault_type, int fault_flags, boolean_t wired, vm_page_t *m_hold) { vm_page_t m; - vm_pindex_t f_first, f_last, pidx; + vm_pindex_t f_first, f_last, f1_first, f1_last, pidx; int rv; MPASS(fs->object == fs->first_object); @@ -357,28 +392,25 @@ vm_fault_populate(struct faultstate *fs, vm_offset_t vaddr, vm_prot_t prot, MPASS(f_last < fs->first_object->size); vm_fault_restore_map_lock(fs); - if (fs->map->timestamp != fs->map_generation) + if (fs->map->timestamp != fs->map_generation) { + vm_fault_populate_cleanup(fs->first_object, f_first, f_last); return (KERN_RESOURCE_SHORTAGE); /* RetryFault */ + } /* Clip pager response to fit into the vm_map_entry. */ - f_first = MAX(OFF_TO_IDX(fs->entry->offset), f_first); - f_last = MIN(OFF_TO_IDX(fs->entry->end - fs->entry->start + + f1_first = MAX(OFF_TO_IDX(fs->entry->offset), f_first); + if (f1_first > f_first) + vm_fault_populate_cleanup(fs->first_object, f_first, f1_first + - 1); + f1_last = MIN(OFF_TO_IDX(fs->entry->end - fs->entry->start + fs->entry->offset), f_last); + if (f1_last < f_last) + vm_fault_populate_cleanup(fs->first_object, f1_last + 1, + f_last); - pidx = f_first; - for (m = vm_page_lookup(fs->first_object, pidx); pidx <= f_last; - pidx++, m = vm_page_next(m)) { - /* - * Check each page to ensure that the driver is - * obeying the interface: the page must be installed - * in the object, fully valid, and exclusively busied. - */ - MPASS(m != NULL); - MPASS(vm_page_xbusied(m)); - MPASS(m->valid == VM_PAGE_BITS_ALL); - MPASS(m->object == fs->first_object); - MPASS(m->pindex == pidx); - + for (pidx = f1_first, m = vm_page_lookup(fs->first_object, pidx); + pidx <= f1_last; pidx++, m = vm_page_next(m)) { + vm_fault_populate_check_page(m, fs->first_object, pidx); vm_fault_dirty(fs->entry, m, prot, fault_type, fault_flags, true); VM_OBJECT_WUNLOCK(fs->first_object);