On 02 Aug 2014, at 17:03 , Alan Cox <a...@rice.edu> wrote:

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

mips, powerpc, sparc64, arm;  yeah very likely.



>> 
>> 
>>> 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
>> 
>> 
> 

— 
Bjoern A. Zeeb             "Come on. Learn, goddamn it.", WarGames, 1983

_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to