Date: Sat, 2 Aug 2014 17:16:53 +0000 From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: Alan Cox <alc@rice.edu> Cc: Alan Cox <alc@FreeBSD.org>, svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r269433 - head/sys/vm Message-ID: <E373E98F-A55F-4DF6-A0CF-20404D7914FB@FreeBSD.org> In-Reply-To: <53DD19F8.9020305@rice.edu> References: <201408021610.s72GAPAd040967@svn.freebsd.org> <EB4AB184-2378-46A5-8391-AD87C242E17C@FreeBSD.org> <53DD19F8.9020305@rice.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
On 02 Aug 2014, at 17:03 , Alan Cox <alc@rice.edu> wrote: > On 08/02/2014 11:54, Bjoern A. Zeeb wrote: >> On 02 Aug 2014, at 16:10 , Alan Cox <alc@FreeBSD.org> wrote: >>=20 >>> Author: alc >>> Date: Sat Aug 2 16:10:24 2014 >>> New Revision: 269433 >>> URL: http://svnweb.freebsd.org/changeset/base/269433 >>>=20 >>> Log: >>> Handle wiring failures in vm_map_wire() with the new functions >>> pmap_unwire() and vm_object_unwire(). >>>=20 >>> Retire vm_fault_{un,}wire(), since they are no longer used. >>>=20 >>> (See r268327 and r269134 for the motivation behind this change.) >>>=20 >>> Reviewed by: kib >>> Sponsored by: EMC / Isilon Storage Division >>>=20 >> 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 >=20 > gcc? >=20 mips, powerpc, sparc64, arm; yeah very likely. >>=20 >>=20 >>> Modified: >>> head/sys/vm/vm_extern.h >>> head/sys/vm/vm_fault.c >>> head/sys/vm/vm_map.c >>>=20 >>> Modified: head/sys/vm/vm_extern.h >>> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >>> --- 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); >>>=20 >>> Modified: head/sys/vm/vm_fault.c >>> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >>> --- 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 >>>=20 >>> 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); >>>=20 >>> #define VM_FAULT_READ_BEHIND 8 >>> #define VM_FAULT_READ_MAX (1 + VM_FAULT_READ_AHEAD_MAX) >>> @@ -1155,68 +1154,6 @@ error:=09 >>> } >>>=20 >>> /* >>> - * 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 =3D start; va < end; va +=3D PAGE_SIZE) { >>> - rv =3D vm_fault(map, va, VM_PROT_NONE, = VM_FAULT_CHANGE_WIRING); >>> - if (rv) { >>> - if (va !=3D 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 =3D 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 =3D start; va < end; va +=3D PAGE_SIZE) { >>> - pa =3D pmap_extract(pmap, va); >>> - if (pa !=3D 0) { >>> - pmap_change_wiring(pmap, va, FALSE); >>> - if (!fictitious) { >>> - m =3D 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: >>>=20 >>> Modified: head/sys/vm/vm_map.c >>> = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D >>> --- 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); >>>=20 >>> #define ENTRY_CHARGED(e) ((e)->cred !=3D NULL || \ >>> ((e)->object.vm_object !=3D NULL && (e)->object.vm_object->cred = !=3D NULL && \ >>> @@ -2418,6 +2420,42 @@ done: >>> } >>>=20 >>> /* >>> + * 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) !=3D 0 && >>> + entry->wired_count =3D=3D 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 =3D -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; >>>=20 >>> if (start =3D=3D end) >>> @@ -2523,17 +2561,24 @@ vm_map_wire(vm_map_t map, vm_offset_t st >>> entry->wired_count++; >>> saved_start =3D entry->start; >>> saved_end =3D entry->end; >>> - fictitious =3D entry->object.vm_object !=3D NULL = && >>> - (entry->object.vm_object->flags & >>> - OBJ_FICTITIOUS) !=3D 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 =3D vm_fault_wire(map, saved_start, = saved_end, >>> - fictitious); >>> + >>> + for (faddr =3D saved_start; faddr < saved_end; = faddr +=3D >>> + PAGE_SIZE) { >>> + /* >>> + * Simulate a fault to get the page and = enter >>> + * it into the physical map. >>> + */ >>> + if ((rv =3D vm_fault(map, faddr, = VM_PROT_NONE, >>> + VM_FAULT_CHANGE_WIRING)) !=3D = KERN_SUCCESS) >>> + break; >>> + } >>> vm_map_lock(map); >>> vm_map_unbusy(map); >>> if (last_timestamp + 1 !=3D map->timestamp) { >>> @@ -2552,23 +2597,22 @@ vm_map_wire(vm_map_t map, vm_offset_t st >>> first_entry =3D NULL; >>> entry =3D tmp_entry; >>> while (entry->end < saved_end) { >>> - if (rv !=3D KERN_SUCCESS) { >>> - = KASSERT(entry->wired_count =3D=3D 1, >>> - ("vm_map_wire: bad = count")); >>> - entry->wired_count =3D = -1; >>> - } >>> + /* >>> + * In case of failure, handle = entries >>> + * that were not fully wired = here; >>> + * fully wired entries are = handled >>> + * later. >>> + */ >>> + if (rv !=3D KERN_SUCCESS && >>> + faddr < entry->end) >>> + = vm_map_wire_entry_failure(map, >>> + entry, faddr); >>> entry =3D entry->next; >>> } >>> } >>> last_timestamp =3D map->timestamp; >>> if (rv !=3D KERN_SUCCESS) { >>> - KASSERT(entry->wired_count =3D=3D 1, >>> - ("vm_map_wire: bad count")); >>> - /* >>> - * Assign an out-of-range value to = represent >>> - * the failure to wire this entry. >>> - */ >>> - entry->wired_count =3D -1; >>> + vm_map_wire_entry_failure(map, entry, = faddr); >>> end =3D entry->end; >>> goto done; >>> } >>> @@ -2632,6 +2676,10 @@ done: >>> entry->wired_count =3D 0; >>> } else if (!user_wire || >>> (entry->eflags & MAP_ENTRY_USER_WIRED) =3D=3D 0) { >>> + /* >>> + * Undo the wiring. Wiring succeeded on this = entry >>> + * but failed on a later entry. =20 >>> + */ >>> if (entry->wired_count =3D=3D 1) >>> vm_map_entry_unwire(map, entry); >>> else >>>=20 >> =97=20 >> Bjoern A. Zeeb "Come on. Learn, goddamn it.", WarGames, = 1983 >>=20 >>=20 >=20 =97=20 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?E373E98F-A55F-4DF6-A0CF-20404D7914FB>