svn commit: r269433 - head/sys/vm

Alan Cox alc at rice.edu
Sat Aug 2 17:03:56 UTC 2014


On 08/02/2014 11:54, Bjoern A. Zeeb wrote:
> On 02 Aug 2014, at 16:10 , Alan Cox <alc at 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
>
>



More information about the svn-src-head mailing list