Skip site navigation (1)Skip section navigation (2)
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>