Date: Sat, 02 Aug 2014 12:03:52 -0500 From: Alan Cox <alc@rice.edu> To: "Bjoern A. Zeeb" <bz@FreeBSD.org>, Alan Cox <alc@FreeBSD.org> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r269433 - head/sys/vm Message-ID: <53DD19F8.9020305@rice.edu> In-Reply-To: <EB4AB184-2378-46A5-8391-AD87C242E17C@FreeBSD.org> References: <201408021610.s72GAPAd040967@svn.freebsd.org> <EB4AB184-2378-46A5-8391-AD87C242E17C@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On 08/02/2014 11:54, Bjoern A. Zeeb wrote: > On 02 Aug 2014, at 16:10 , Alan Cox <alc@FreeBSD.org> wrote: > >> Author: alc >> Date: Sat Aug 2 16:10:24 2014 >> New Revision: 269433 >> URL: http://svnweb.freebsd.org/changeset/base/269433 >> >> Log: >> Handle wiring failures in vm_map_wire() with the new functions >> pmap_unwire() and vm_object_unwire(). >> >> Retire vm_fault_{un,}wire(), since they are no longer used. >> >> (See r268327 and r269134 for the motivation behind this change.) >> >> Reviewed by: kib >> Sponsored by: EMC / Isilon Storage Division >> > cc1: warnings being treated as errors > /scratch/tmp/bz/head.svn/sys/vm/vm_map.c: In function 'vm_map_wire': > /scratch/tmp/bz/head.svn/sys/vm/vm_map.c:2470: warning: 'rv' may be used uninitialized in this function > --- vm_map.o --- > *** [vm_map.o] Error code 1 gcc? > > >> Modified: >> head/sys/vm/vm_extern.h >> head/sys/vm/vm_fault.c >> head/sys/vm/vm_map.c >> >> Modified: head/sys/vm/vm_extern.h >> ============================================================================== >> --- head/sys/vm/vm_extern.h Sat Aug 2 15:05:23 2014 (r269432) >> +++ head/sys/vm/vm_extern.h Sat Aug 2 16:10:24 2014 (r269433) >> @@ -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); >> -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 *); >> int vm_mmap(vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int, objtype_t, void *, vm_ooffset_t); >> >> Modified: head/sys/vm/vm_fault.c >> ============================================================================== >> --- head/sys/vm/vm_fault.c Sat Aug 2 15:05:23 2014 (r269432) >> +++ head/sys/vm/vm_fault.c Sat Aug 2 16:10:24 2014 (r269433) >> @@ -106,7 +106,6 @@ __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) >> @@ -1155,68 +1154,6 @@ error: >> } >> >> /* >> - * vm_fault_wire: >> - * >> - * Wire down a range of virtual addresses in a map. >> - */ >> -int >> -vm_fault_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, >> - boolean_t fictitious) >> -{ >> - vm_offset_t va; >> - int rv; >> - >> - /* >> - * We simulate a fault to get the page and enter it in the physical >> - * map. For user wiring, we only ask for read access on currently >> - * read-only sections. >> - */ >> - for (va = start; va < end; va += PAGE_SIZE) { >> - rv = vm_fault(map, va, VM_PROT_NONE, VM_FAULT_CHANGE_WIRING); >> - if (rv) { >> - if (va != start) >> - vm_fault_unwire(map, start, va, fictitious); >> - return (rv); >> - } >> - } >> - return (KERN_SUCCESS); >> -} >> - >> -/* >> - * vm_fault_unwire: >> - * >> - * Unwire a range of virtual addresses in a map. >> - */ >> -static void >> -vm_fault_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end, >> - boolean_t fictitious) >> -{ >> - vm_paddr_t pa; >> - vm_offset_t va; >> - vm_page_t m; >> - pmap_t pmap; >> - >> - pmap = vm_map_pmap(map); >> - >> - /* >> - * Since the pages are wired down, we must be able to get their >> - * mappings from the physical map system. >> - */ >> - for (va = start; va < end; va += PAGE_SIZE) { >> - pa = pmap_extract(pmap, va); >> - if (pa != 0) { >> - pmap_change_wiring(pmap, va, FALSE); >> - if (!fictitious) { >> - m = PHYS_TO_VM_PAGE(pa); >> - vm_page_lock(m); >> - vm_page_unwire(m, PQ_ACTIVE); >> - vm_page_unlock(m); >> - } >> - } >> - } >> -} >> - >> -/* >> * Routine: >> * vm_fault_copy_entry >> * Function: >> >> Modified: head/sys/vm/vm_map.c >> ============================================================================== >> --- head/sys/vm/vm_map.c Sat Aug 2 15:05:23 2014 (r269432) >> +++ head/sys/vm/vm_map.c Sat Aug 2 16:10:24 2014 (r269433) >> @@ -140,6 +140,8 @@ static void vmspace_zdtor(void *mem, int >> static int vm_map_stack_locked(vm_map_t map, vm_offset_t addrbos, >> vm_size_t max_ssize, vm_size_t growsize, vm_prot_t prot, vm_prot_t max, >> int cow); >> +static void vm_map_wire_entry_failure(vm_map_t map, vm_map_entry_t entry, >> + vm_offset_t failed_addr); >> >> #define ENTRY_CHARGED(e) ((e)->cred != NULL || \ >> ((e)->object.vm_object != NULL && (e)->object.vm_object->cred != NULL && \ >> @@ -2418,6 +2420,42 @@ done: >> } >> >> /* >> + * vm_map_wire_entry_failure: >> + * >> + * Handle a wiring failure on the given entry. >> + * >> + * The map should be locked. >> + */ >> +static void >> +vm_map_wire_entry_failure(vm_map_t map, vm_map_entry_t entry, >> + vm_offset_t failed_addr) >> +{ >> + >> + VM_MAP_ASSERT_LOCKED(map); >> + KASSERT((entry->eflags & MAP_ENTRY_IN_TRANSITION) != 0 && >> + entry->wired_count == 1, >> + ("vm_map_wire_entry_failure: entry %p isn't being wired", entry)); >> + KASSERT(failed_addr < entry->end, >> + ("vm_map_wire_entry_failure: entry %p was fully wired", entry)); >> + >> + /* >> + * If any pages at the start of this entry were successfully wired, >> + * then unwire them. >> + */ >> + if (failed_addr > entry->start) { >> + pmap_unwire(map->pmap, entry->start, failed_addr); >> + vm_object_unwire(entry->object.vm_object, entry->offset, >> + failed_addr - entry->start, PQ_ACTIVE); >> + } >> + >> + /* >> + * Assign an out-of-range value to represent the failure to wire this >> + * entry. >> + */ >> + entry->wired_count = -1; >> +} >> + >> +/* >> * vm_map_wire: >> * >> * Implements both kernel and user wiring. >> @@ -2427,10 +2465,10 @@ vm_map_wire(vm_map_t map, vm_offset_t st >> int flags) >> { >> vm_map_entry_t entry, first_entry, tmp_entry; >> - vm_offset_t saved_end, saved_start; >> + vm_offset_t faddr, saved_end, saved_start; >> unsigned int last_timestamp; >> int rv; >> - boolean_t fictitious, need_wakeup, result, user_wire; >> + boolean_t need_wakeup, result, user_wire; >> vm_prot_t prot; >> >> if (start == end) >> @@ -2523,17 +2561,24 @@ vm_map_wire(vm_map_t map, vm_offset_t st >> entry->wired_count++; >> saved_start = entry->start; >> saved_end = entry->end; >> - fictitious = entry->object.vm_object != NULL && >> - (entry->object.vm_object->flags & >> - OBJ_FICTITIOUS) != 0; >> + >> /* >> * Release the map lock, relying on the in-transition >> * mark. Mark the map busy for fork. >> */ >> vm_map_busy(map); >> vm_map_unlock(map); >> - rv = vm_fault_wire(map, saved_start, saved_end, >> - fictitious); >> + >> + for (faddr = saved_start; faddr < saved_end; faddr += >> + PAGE_SIZE) { >> + /* >> + * Simulate a fault to get the page and enter >> + * it into the physical map. >> + */ >> + if ((rv = vm_fault(map, faddr, VM_PROT_NONE, >> + VM_FAULT_CHANGE_WIRING)) != KERN_SUCCESS) >> + break; >> + } >> vm_map_lock(map); >> vm_map_unbusy(map); >> if (last_timestamp + 1 != map->timestamp) { >> @@ -2552,23 +2597,22 @@ vm_map_wire(vm_map_t map, vm_offset_t st >> first_entry = NULL; >> entry = tmp_entry; >> while (entry->end < saved_end) { >> - if (rv != KERN_SUCCESS) { >> - KASSERT(entry->wired_count == 1, >> - ("vm_map_wire: bad count")); >> - entry->wired_count = -1; >> - } >> + /* >> + * In case of failure, handle entries >> + * that were not fully wired here; >> + * fully wired entries are handled >> + * later. >> + */ >> + if (rv != KERN_SUCCESS && >> + faddr < entry->end) >> + vm_map_wire_entry_failure(map, >> + entry, faddr); >> entry = entry->next; >> } >> } >> last_timestamp = map->timestamp; >> if (rv != KERN_SUCCESS) { >> - KASSERT(entry->wired_count == 1, >> - ("vm_map_wire: bad count")); >> - /* >> - * Assign an out-of-range value to represent >> - * the failure to wire this entry. >> - */ >> - entry->wired_count = -1; >> + vm_map_wire_entry_failure(map, entry, faddr); >> end = entry->end; >> goto done; >> } >> @@ -2632,6 +2676,10 @@ done: >> entry->wired_count = 0; >> } else if (!user_wire || >> (entry->eflags & MAP_ENTRY_USER_WIRED) == 0) { >> + /* >> + * Undo the wiring. Wiring succeeded on this entry >> + * but failed on a later entry. >> + */ >> if (entry->wired_count == 1) >> vm_map_entry_unwire(map, entry); >> else >> > — > Bjoern A. Zeeb "Come on. Learn, goddamn it.", WarGames, 1983 > >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53DD19F8.9020305>