From owner-svn-src-head@FreeBSD.ORG Thu Aug 28 16:52:53 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id B7E7C54D; Thu, 28 Aug 2014 16:52:53 +0000 (UTC) Received: from mail-qg0-x235.google.com (mail-qg0-x235.google.com [IPv6:2607:f8b0:400d:c04::235]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 3394F10AF; Thu, 28 Aug 2014 16:52:53 +0000 (UTC) Received: by mail-qg0-f53.google.com with SMTP id z107so1043115qgd.12 for ; Thu, 28 Aug 2014 09:52:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=S9RWw1nkznXa+q+d+0Fh6z/S+8JOgQ/xnQ8lufMrscQ=; b=mi+l7TkX8/XuGiFr5tJlJEtoqlINTq20ZN7sWI/KWA61k2WnfeEQRtH8j2gHXsV5u9 yS7IzmELAnyInZR4HijjpArwxiVmtwutSTFm/XoO5yT/5QGA/cvu4eDkKgaIv91c1/L1 KNqcbpCHKV9xFrYeFHZUFin/bBB1B+eGm2/jPqy/fw6nYMMNd2CrVGaVclq/swaVG9Sr 7rgDhqn/CuLqIQCvjUAgoz1F1WuBA2E1HIb2PStfAwTVI+CXaJG9aRejzCKL034uw38e 8cVZYzPFzey+OetnHvIhQkgAZWYYplsnAFUxOiqmkrxP7zA5JoUXyqJiDOQRoM5P9Nk4 y5vA== MIME-Version: 1.0 X-Received: by 10.140.85.74 with SMTP id m68mr8064085qgd.50.1409244772258; Thu, 28 Aug 2014 09:52:52 -0700 (PDT) Sender: hiren.panchasara@gmail.com Received: by 10.96.170.230 with HTTP; Thu, 28 Aug 2014 09:52:52 -0700 (PDT) In-Reply-To: <72B80282-6FA1-4481-8333-37EF3A58FB74@rice.edu> References: <201407261810.s6QIAIIj049439@svn.freebsd.org> <72B80282-6FA1-4481-8333-37EF3A58FB74@rice.edu> Date: Thu, 28 Aug 2014 09:52:52 -0700 X-Google-Sender-Auth: Cq3Z2_sPJUl7cCcsHP-Vy456U_Q Message-ID: Subject: Re: svn commit: r269134 - head/sys/vm From: hiren panchasara To: Alan Cox Content-Type: text/plain; charset=UTF-8 Cc: Alan Cox , "svn-src-head@freebsd.org" , Adrian Chadd , "src-committers@freebsd.org" , "svn-src-all@freebsd.org" X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Aug 2014 16:52:53 -0000 On Thu, Aug 28, 2014 at 9:30 AM, Alan Cox wrote: > > On Aug 28, 2014, at 3:30 AM, Adrian Chadd wrote: > >> Hi Alan! >> >> I just reverted back to the commit before this one and it fixed my MIPS32 boot. >> >> Would you have some time to help me help you figure out why things broke? :) >> > > > Have you tried booting a kernel based on r269134? At the time, I tested a 64-bit MIPS kernel on gxemul, and it ran ok. Also, Hiren reports that a 32-bit kernel from about two weeks after r269134 works for him. > To be precise, I am on r269799 which works for me. cheers, Hiren > >> >> >> >> >> -a >> >> >> On 26 July 2014 11:10, Alan Cox wrote: >>> Author: alc >>> Date: Sat Jul 26 18:10:18 2014 >>> New Revision: 269134 >>> URL: http://svnweb.freebsd.org/changeset/base/269134 >>> >>> Log: >>> When unwiring a region of an address space, do not assume that the >>> underlying physical pages are mapped by the pmap. If, for example, the >>> application has performed an mprotect(..., PROT_NONE) on any part of the >>> wired region, then those pages will no longer be mapped by the pmap. >>> So, using the pmap to lookup the wired pages in order to unwire them >>> doesn't always work, and when it doesn't work wired pages are leaked. >>> >>> To avoid the leak, introduce and use a new function vm_object_unwire() >>> that locates the wired pages by traversing the object and its backing >>> objects. >>> >>> At the same time, switch from using pmap_change_wiring() to the recently >>> introduced function pmap_unwire() for unwiring the region's mappings. >>> pmap_unwire() is faster, because it operates a range of virtual addresses >>> rather than a single virtual page at a time. Moreover, by operating on >>> a range, it is superpage friendly. It doesn't waste time performing >>> unnecessary demotions. >>> >>> Reported by: markj >>> Reviewed by: kib >>> Tested by: pho, jmg (arm) >>> Sponsored by: EMC / Isilon Storage Division >>> >>> Modified: >>> head/sys/vm/vm_extern.h >>> head/sys/vm/vm_fault.c >>> head/sys/vm/vm_map.c >>> head/sys/vm/vm_object.c >>> head/sys/vm/vm_object.h >>> >>> Modified: head/sys/vm/vm_extern.h >>> ============================================================================== >>> --- head/sys/vm/vm_extern.h Sat Jul 26 17:59:25 2014 (r269133) >>> +++ head/sys/vm/vm_extern.h Sat Jul 26 18:10:18 2014 (r269134) >>> @@ -81,7 +81,6 @@ int vm_fault_hold(vm_map_t map, vm_offse >>> int fault_flags, vm_page_t *m_hold); >>> int vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len, >>> vm_prot_t prot, vm_page_t *ma, int max_count); >>> -void vm_fault_unwire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t); >>> int vm_fault_wire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t); >>> int vm_forkproc(struct thread *, struct proc *, struct thread *, struct vmspace *, int); >>> void vm_waitproc(struct proc *); >>> >>> Modified: head/sys/vm/vm_fault.c >>> ============================================================================== >>> --- head/sys/vm/vm_fault.c Sat Jul 26 17:59:25 2014 (r269133) >>> +++ head/sys/vm/vm_fault.c Sat Jul 26 18:10:18 2014 (r269134) >>> @@ -106,6 +106,7 @@ __FBSDID("$FreeBSD$"); >>> #define PFFOR 4 >>> >>> static int vm_fault_additional_pages(vm_page_t, int, int, vm_page_t *, int *); >>> +static void vm_fault_unwire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t); >>> >>> #define VM_FAULT_READ_BEHIND 8 >>> #define VM_FAULT_READ_MAX (1 + VM_FAULT_READ_AHEAD_MAX) >>> @@ -1186,7 +1187,7 @@ vm_fault_wire(vm_map_t map, vm_offset_t >>> * >>> * Unwire a range of virtual addresses in a map. >>> */ >>> -void >>> +static void >>> vm_fault_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end, >>> boolean_t fictitious) >>> { >>> >>> Modified: head/sys/vm/vm_map.c >>> ============================================================================== >>> --- head/sys/vm/vm_map.c Sat Jul 26 17:59:25 2014 (r269133) >>> +++ head/sys/vm/vm_map.c Sat Jul 26 18:10:18 2014 (r269134) >>> @@ -132,6 +132,7 @@ static void _vm_map_init(vm_map_t map, p >>> vm_offset_t max); >>> static void vm_map_entry_deallocate(vm_map_entry_t entry, boolean_t system_map); >>> static void vm_map_entry_dispose(vm_map_t map, vm_map_entry_t entry); >>> +static void vm_map_entry_unwire(vm_map_t map, vm_map_entry_t entry); >>> #ifdef INVARIANTS >>> static void vm_map_zdtor(void *mem, int size, void *arg); >>> static void vmspace_zdtor(void *mem, int size, void *arg); >>> @@ -2393,16 +2394,10 @@ done: >>> (entry->eflags & MAP_ENTRY_USER_WIRED))) { >>> if (user_unwire) >>> entry->eflags &= ~MAP_ENTRY_USER_WIRED; >>> - entry->wired_count--; >>> - if (entry->wired_count == 0) { >>> - /* >>> - * Retain the map lock. >>> - */ >>> - vm_fault_unwire(map, entry->start, entry->end, >>> - entry->object.vm_object != NULL && >>> - (entry->object.vm_object->flags & >>> - OBJ_FICTITIOUS) != 0); >>> - } >>> + if (entry->wired_count == 1) >>> + vm_map_entry_unwire(map, entry); >>> + else >>> + entry->wired_count--; >>> } >>> KASSERT((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0, >>> ("vm_map_unwire: in-transition flag missing %p", entry)); >>> @@ -2635,19 +2630,12 @@ done: >>> * unnecessary. >>> */ >>> entry->wired_count = 0; >>> - } else { >>> - if (!user_wire || >>> - (entry->eflags & MAP_ENTRY_USER_WIRED) == 0) >>> + } else if (!user_wire || >>> + (entry->eflags & MAP_ENTRY_USER_WIRED) == 0) { >>> + if (entry->wired_count == 1) >>> + vm_map_entry_unwire(map, entry); >>> + else >>> entry->wired_count--; >>> - if (entry->wired_count == 0) { >>> - /* >>> - * Retain the map lock. >>> - */ >>> - vm_fault_unwire(map, entry->start, entry->end, >>> - entry->object.vm_object != NULL && >>> - (entry->object.vm_object->flags & >>> - OBJ_FICTITIOUS) != 0); >>> - } >>> } >>> next_entry_done: >>> KASSERT((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0, >>> @@ -2783,9 +2771,13 @@ vm_map_sync( >>> static void >>> vm_map_entry_unwire(vm_map_t map, vm_map_entry_t entry) >>> { >>> - vm_fault_unwire(map, entry->start, entry->end, >>> - entry->object.vm_object != NULL && >>> - (entry->object.vm_object->flags & OBJ_FICTITIOUS) != 0); >>> + >>> + VM_MAP_ASSERT_LOCKED(map); >>> + KASSERT(entry->wired_count > 0, >>> + ("vm_map_entry_unwire: entry %p isn't wired", entry)); >>> + pmap_unwire(map->pmap, entry->start, entry->end); >>> + vm_object_unwire(entry->object.vm_object, entry->offset, entry->end - >>> + entry->start, PQ_ACTIVE); >>> entry->wired_count = 0; >>> } >>> >>> >>> Modified: head/sys/vm/vm_object.c >>> ============================================================================== >>> --- head/sys/vm/vm_object.c Sat Jul 26 17:59:25 2014 (r269133) >>> +++ head/sys/vm/vm_object.c Sat Jul 26 18:10:18 2014 (r269134) >>> @@ -2202,6 +2202,78 @@ vm_object_set_writeable_dirty(vm_object_ >>> vm_object_set_flag(object, OBJ_MIGHTBEDIRTY); >>> } >>> >>> +/* >>> + * vm_object_unwire: >>> + * >>> + * For each page offset within the specified range of the given object, >>> + * find the highest-level page in the shadow chain and unwire it. A page >>> + * must exist at every page offset, and the highest-level page must be >>> + * wired. >>> + */ >>> +void >>> +vm_object_unwire(vm_object_t object, vm_ooffset_t offset, vm_size_t length, >>> + uint8_t queue) >>> +{ >>> + vm_object_t tobject; >>> + vm_page_t m, tm; >>> + vm_pindex_t end_pindex, pindex, tpindex; >>> + int depth, locked_depth; >>> + >>> + KASSERT((offset & PAGE_MASK) == 0, >>> + ("vm_object_unwire: offset is not page aligned")); >>> + KASSERT((length & PAGE_MASK) == 0, >>> + ("vm_object_unwire: length is not a multiple of PAGE_SIZE")); >>> + /* The wired count of a fictitious page never changes. */ >>> + if ((object->flags & OBJ_FICTITIOUS) != 0) >>> + return; >>> + pindex = OFF_TO_IDX(offset); >>> + end_pindex = pindex + atop(length); >>> + locked_depth = 1; >>> + VM_OBJECT_RLOCK(object); >>> + m = vm_page_find_least(object, pindex); >>> + while (pindex < end_pindex) { >>> + if (m == NULL || pindex < m->pindex) { >>> + /* >>> + * The first object in the shadow chain doesn't >>> + * contain a page at the current index. Therefore, >>> + * the page must exist in a backing object. >>> + */ >>> + tobject = object; >>> + tpindex = pindex; >>> + depth = 0; >>> + do { >>> + tpindex += >>> + OFF_TO_IDX(tobject->backing_object_offset); >>> + tobject = tobject->backing_object; >>> + KASSERT(tobject != NULL, >>> + ("vm_object_unwire: missing page")); >>> + if ((tobject->flags & OBJ_FICTITIOUS) != 0) >>> + goto next_page; >>> + depth++; >>> + if (depth == locked_depth) { >>> + locked_depth++; >>> + VM_OBJECT_RLOCK(tobject); >>> + } >>> + } while ((tm = vm_page_lookup(tobject, tpindex)) == >>> + NULL); >>> + } else { >>> + tm = m; >>> + m = TAILQ_NEXT(m, listq); >>> + } >>> + vm_page_lock(tm); >>> + vm_page_unwire(tm, queue); >>> + vm_page_unlock(tm); >>> +next_page: >>> + pindex++; >>> + } >>> + /* Release the accumulated object locks. */ >>> + for (depth = 0; depth < locked_depth; depth++) { >>> + tobject = object->backing_object; >>> + VM_OBJECT_RUNLOCK(object); >>> + object = tobject; >>> + } >>> +} >>> + >>> #include "opt_ddb.h" >>> #ifdef DDB >>> #include >>> >>> Modified: head/sys/vm/vm_object.h >>> ============================================================================== >>> --- head/sys/vm/vm_object.h Sat Jul 26 17:59:25 2014 (r269133) >>> +++ head/sys/vm/vm_object.h Sat Jul 26 18:10:18 2014 (r269134) >>> @@ -291,6 +291,8 @@ void vm_object_shadow (vm_object_t *, vm >>> void vm_object_split(vm_map_entry_t); >>> boolean_t vm_object_sync(vm_object_t, vm_ooffset_t, vm_size_t, boolean_t, >>> boolean_t); >>> +void vm_object_unwire(vm_object_t object, vm_ooffset_t offset, >>> + vm_size_t length, uint8_t queue); >>> #endif /* _KERNEL */ >>> >>> #endif /* _VM_OBJECT_ */ >>> >> > >