vm_map.c (17294) | vm_map.c (17334) |
---|---|
1/* 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * The Mach Operating System project at Carnegie-Mellon University. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 47 unchanged lines hidden (view full) --- 56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 57 * School of Computer Science 58 * Carnegie Mellon University 59 * Pittsburgh PA 15213-3890 60 * 61 * any improvements or extensions that they make and grant Carnegie the 62 * rights to redistribute these changes. 63 * | 1/* 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * The Mach Operating System project at Carnegie-Mellon University. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 47 unchanged lines hidden (view full) --- 56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 57 * School of Computer Science 58 * Carnegie Mellon University 59 * Pittsburgh PA 15213-3890 60 * 61 * any improvements or extensions that they make and grant Carnegie the 62 * rights to redistribute these changes. 63 * |
64 * $Id: vm_map.c,v 1.52 1996/07/07 03:27:41 davidg Exp $ | 64 * $Id: vm_map.c,v 1.53 1996/07/27 03:23:56 dyson Exp $ |
65 */ 66 67/* 68 * Virtual memory mapping module. 69 */ 70#include "opt_ddb.h" 71 72#include <sys/param.h> --- 94 unchanged lines hidden (view full) --- 167static void _vm_map_clip_start __P((vm_map_t, vm_map_entry_t, vm_offset_t)); 168static vm_map_entry_t vm_map_entry_create __P((vm_map_t)); 169static void vm_map_entry_delete __P((vm_map_t, vm_map_entry_t)); 170static __inline void vm_map_entry_dispose __P((vm_map_t, vm_map_entry_t)); 171static void vm_map_entry_unwire __P((vm_map_t, vm_map_entry_t)); 172static void vm_map_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, 173 vm_map_entry_t)); 174static void vm_map_simplify_entry __P((vm_map_t, vm_map_entry_t)); | 65 */ 66 67/* 68 * Virtual memory mapping module. 69 */ 70#include "opt_ddb.h" 71 72#include <sys/param.h> --- 94 unchanged lines hidden (view full) --- 167static void _vm_map_clip_start __P((vm_map_t, vm_map_entry_t, vm_offset_t)); 168static vm_map_entry_t vm_map_entry_create __P((vm_map_t)); 169static void vm_map_entry_delete __P((vm_map_t, vm_map_entry_t)); 170static __inline void vm_map_entry_dispose __P((vm_map_t, vm_map_entry_t)); 171static void vm_map_entry_unwire __P((vm_map_t, vm_map_entry_t)); 172static void vm_map_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, 173 vm_map_entry_t)); 174static void vm_map_simplify_entry __P((vm_map_t, vm_map_entry_t)); |
175static __pure int vm_map_simplify_okay __P((vm_map_entry_t entry1, 176 vm_map_entry_t entry2)); | |
177 178void 179vm_map_startup() 180{ 181 register int i; 182 register vm_map_entry_t mep; 183 vm_map_t mp; 184 --- 42 unchanged lines hidden (view full) --- 227 if (!mapvm) 228 mapvmpgcnt = 0; 229 } 230 MALLOC(vm, struct vmspace *, sizeof(struct vmspace), M_VMMAP, M_WAITOK); 231 bzero(vm, (caddr_t) &vm->vm_startcopy - (caddr_t) vm); 232 vm_map_init(&vm->vm_map, min, max, pageable); 233 pmap_pinit(&vm->vm_pmap); 234 vm->vm_map.pmap = &vm->vm_pmap; /* XXX */ | 175 176void 177vm_map_startup() 178{ 179 register int i; 180 register vm_map_entry_t mep; 181 vm_map_t mp; 182 --- 42 unchanged lines hidden (view full) --- 225 if (!mapvm) 226 mapvmpgcnt = 0; 227 } 228 MALLOC(vm, struct vmspace *, sizeof(struct vmspace), M_VMMAP, M_WAITOK); 229 bzero(vm, (caddr_t) &vm->vm_startcopy - (caddr_t) vm); 230 vm_map_init(&vm->vm_map, min, max, pageable); 231 pmap_pinit(&vm->vm_pmap); 232 vm->vm_map.pmap = &vm->vm_pmap; /* XXX */ |
233 vm->vm_pmap.pm_map = &vm->vm_map; |
|
235 vm->vm_refcnt = 1; 236 return (vm); 237} 238 239void 240vmspace_free(vm) 241 register struct vmspace *vm; 242{ --- 387 unchanged lines hidden (view full) --- 630 * Assert that the next entry doesn't overlap the end point. 631 */ 632 633 if ((prev_entry->next != &map->header) && 634 (prev_entry->next->start < end)) 635 return (KERN_NO_SPACE); 636 637 if ((prev_entry != &map->header) && | 234 vm->vm_refcnt = 1; 235 return (vm); 236} 237 238void 239vmspace_free(vm) 240 register struct vmspace *vm; 241{ --- 387 unchanged lines hidden (view full) --- 629 * Assert that the next entry doesn't overlap the end point. 630 */ 631 632 if ((prev_entry->next != &map->header) && 633 (prev_entry->next->start < end)) 634 return (KERN_NO_SPACE); 635 636 if ((prev_entry != &map->header) && |
638 (object == NULL) && | |
639 (prev_entry->end == start) && | 637 (prev_entry->end == start) && |
638 ((object == NULL) || (prev_entry->object.vm_object == object)) && |
|
640 (prev_entry->is_a_map == FALSE) && 641 (prev_entry->is_sub_map == FALSE) && 642 (prev_entry->inheritance == VM_INHERIT_DEFAULT) && 643 (prev_entry->protection == prot) && 644 (prev_entry->max_protection == max) && 645 (prev_entry->wired_count == 0)) { 646 647 648 /* 649 * See if we can avoid creating a new entry by extending one of our 650 * neighbors. 651 */ | 639 (prev_entry->is_a_map == FALSE) && 640 (prev_entry->is_sub_map == FALSE) && 641 (prev_entry->inheritance == VM_INHERIT_DEFAULT) && 642 (prev_entry->protection == prot) && 643 (prev_entry->max_protection == max) && 644 (prev_entry->wired_count == 0)) { 645 646 647 /* 648 * See if we can avoid creating a new entry by extending one of our 649 * neighbors. 650 */ |
652 if (vm_object_coalesce(prev_entry->object.vm_object, 653 OFF_TO_IDX(prev_entry->offset), 654 (vm_size_t) (prev_entry->end 655 - prev_entry->start), 656 (vm_size_t) (end - prev_entry->end))) { | 651 if (object == NULL) { 652 if (vm_object_coalesce(prev_entry->object.vm_object, 653 OFF_TO_IDX(prev_entry->offset), 654 (vm_size_t) (prev_entry->end 655 - prev_entry->start), 656 (vm_size_t) (end - prev_entry->end))) { |
657 | 657 |
658 /* 659 * Coalesced the two objects - can extend the 660 * previous map entry to include the new 661 * range. 662 */ 663 map->size += (end - prev_entry->end); 664 prev_entry->end = end; 665 prev_object = prev_entry->object.vm_object; 666 default_pager_convert_to_swapq(prev_object); 667 return (KERN_SUCCESS); | 658 /* 659 * Coalesced the two objects - can extend the 660 * previous map entry to include the new 661 * range. 662 */ 663 map->size += (end - prev_entry->end); 664 prev_entry->end = end; 665 prev_object = prev_entry->object.vm_object; 666 default_pager_convert_to_swapq(prev_object); 667 return (KERN_SUCCESS); 668 } |
668 } 669 } 670 /* 671 * Create a new entry 672 */ 673 674 new_entry = vm_map_entry_create(map); 675 new_entry->start = start; --- 25 unchanged lines hidden (view full) --- 701 */ 702 703 vm_map_entry_link(map, prev_entry, new_entry); 704 map->size += new_entry->end - new_entry->start; 705 706 /* 707 * Update the free space hint 708 */ | 669 } 670 } 671 /* 672 * Create a new entry 673 */ 674 675 new_entry = vm_map_entry_create(map); 676 new_entry->start = start; --- 25 unchanged lines hidden (view full) --- 702 */ 703 704 vm_map_entry_link(map, prev_entry, new_entry); 705 map->size += new_entry->end - new_entry->start; 706 707 /* 708 * Update the free space hint 709 */ |
709 if (map->first_free == prev_entry) { 710 if (prev_entry->end == new_entry->start) 711 map->first_free = new_entry; 712 } | 710 if ((map->first_free == prev_entry) && 711 (prev_entry->end >= new_entry->start)) 712 map->first_free = new_entry; |
713 714 default_pager_convert_to_swapq(object); 715 return (KERN_SUCCESS); 716} 717 718/* 719 * Find sufficient space for `length' bytes in the given map, starting at 720 * `start'. The map must be locked. Returns 0 on success, 1 on no space. --- 13 unchanged lines hidden (view full) --- 734 if (start > map->max_offset) 735 return (1); 736 737 /* 738 * Look for the first possible address; if there's already something 739 * at this address, we have to start after it. 740 */ 741 if (start == map->min_offset) { | 713 714 default_pager_convert_to_swapq(object); 715 return (KERN_SUCCESS); 716} 717 718/* 719 * Find sufficient space for `length' bytes in the given map, starting at 720 * `start'. The map must be locked. Returns 0 on success, 1 on no space. --- 13 unchanged lines hidden (view full) --- 734 if (start > map->max_offset) 735 return (1); 736 737 /* 738 * Look for the first possible address; if there's already something 739 * at this address, we have to start after it. 740 */ 741 if (start == map->min_offset) { |
742 if ((entry = map->first_free) != &map->header) { | 742 if ((entry = map->first_free) != &map->header) |
743 start = entry->end; | 743 start = entry->end; |
744 } | |
745 } else { 746 vm_map_entry_t tmp; 747 748 if (vm_map_lookup_entry(map, start, &tmp)) 749 start = tmp->end; 750 entry = tmp; 751 } 752 --- 64 unchanged lines hidden (view full) --- 817 vm_map_unlock(map); 818 819 if (map == kmem_map || map == mb_map) 820 splx(s); 821 822 return (result); 823} 824 | 744 } else { 745 vm_map_entry_t tmp; 746 747 if (vm_map_lookup_entry(map, start, &tmp)) 748 start = tmp->end; 749 entry = tmp; 750 } 751 --- 64 unchanged lines hidden (view full) --- 816 vm_map_unlock(map); 817 818 if (map == kmem_map || map == mb_map) 819 splx(s); 820 821 return (result); 822} 823 |
825static __pure int 826vm_map_simplify_okay(entry1, entry2) 827 vm_map_entry_t entry1, entry2; 828{ 829 if ((entry1->end != entry2->start) || 830 (entry1->object.vm_object != entry2->object.vm_object)) 831 return 0; 832 if (entry1->object.vm_object) { 833 if (entry1->object.vm_object->behavior != 834 entry2->object.vm_object->behavior) 835 return 0; 836 if (entry1->offset + (entry1->end - entry1->start) != 837 entry2->offset) 838 return 0; 839 } 840 if ((entry1->needs_copy != entry2->needs_copy) || 841 (entry1->copy_on_write != entry2->copy_on_write) || 842 (entry1->protection != entry2->protection) || 843 (entry1->max_protection != entry2->max_protection) || 844 (entry1->inheritance != entry2->inheritance) || 845 (entry1->is_sub_map != FALSE) || 846 (entry1->is_a_map != FALSE) || 847 (entry1->wired_count != 0) || 848 (entry2->is_sub_map != FALSE) || 849 (entry2->is_a_map != FALSE) || 850 (entry2->wired_count != 0)) 851 return 0; 852 853 return 1; 854} 855 | |
856/* 857 * vm_map_simplify_entry: [ internal use only ] | 824/* 825 * vm_map_simplify_entry: [ internal use only ] |
826 * 827 * Simplify the given map entry by: 828 * removing extra sharing maps 829 * [XXX maybe later] merging with a neighbor |
|
858 */ 859static void 860vm_map_simplify_entry(map, entry) 861 vm_map_t map; 862 vm_map_entry_t entry; 863{ 864 vm_map_entry_t next, prev; | 830 */ 831static void 832vm_map_simplify_entry(map, entry) 833 vm_map_t map; 834 vm_map_entry_t entry; 835{ 836 vm_map_entry_t next, prev; |
837 vm_size_t nextsize, prevsize, esize; |
|
865 | 838 |
866 if (entry->is_a_map || entry->is_sub_map || entry->wired_count) | 839 /* 840 * If this entry corresponds to a sharing map, then see if we can 841 * remove the level of indirection. If it's not a sharing map, then it 842 * points to a VM object, so see if we can merge with either of our 843 * neighbors. 844 */ 845 846 if (entry->is_sub_map || entry->is_a_map || entry->wired_count) |
867 return; 868 869 prev = entry->prev; 870 if (prev != &map->header) { | 847 return; 848 849 prev = entry->prev; 850 if (prev != &map->header) { |
871 if ( vm_map_simplify_okay(prev, entry)) { | 851 prevsize = prev->end - prev->start; 852 if ( (prev->end == entry->start) && 853 (prev->object.vm_object == entry->object.vm_object) && 854 (!prev->object.vm_object || (prev->object.vm_object->behavior == entry->object.vm_object->behavior)) && 855 (!prev->object.vm_object || 856 (prev->offset + prevsize == entry->offset)) && 857 (prev->needs_copy == entry->needs_copy) && 858 (prev->copy_on_write == entry->copy_on_write) && 859 (prev->protection == entry->protection) && 860 (prev->max_protection == entry->max_protection) && 861 (prev->inheritance == entry->inheritance) && 862 (prev->is_a_map == FALSE) && 863 (prev->is_sub_map == FALSE) && 864 (prev->wired_count == 0)) { |
872 if (map->first_free == prev) 873 map->first_free = entry; 874 if (map->hint == prev) 875 map->hint = entry; 876 vm_map_entry_unlink(map, prev); 877 entry->start = prev->start; 878 entry->offset = prev->offset; 879 if (prev->object.vm_object) 880 vm_object_deallocate(prev->object.vm_object); 881 vm_map_entry_dispose(map, prev); 882 } 883 } 884 885 next = entry->next; 886 if (next != &map->header) { | 865 if (map->first_free == prev) 866 map->first_free = entry; 867 if (map->hint == prev) 868 map->hint = entry; 869 vm_map_entry_unlink(map, prev); 870 entry->start = prev->start; 871 entry->offset = prev->offset; 872 if (prev->object.vm_object) 873 vm_object_deallocate(prev->object.vm_object); 874 vm_map_entry_dispose(map, prev); 875 } 876 } 877 878 next = entry->next; 879 if (next != &map->header) { |
887 if ( vm_map_simplify_okay(entry, next)) { | 880 nextsize = next->end - next->start; 881 esize = entry->end - entry->start; 882 if ((entry->end == next->start) && 883 (next->object.vm_object == entry->object.vm_object) && 884 (!next->object.vm_object || (next->object.vm_object->behavior == entry->object.vm_object->behavior)) && 885 (!entry->object.vm_object || 886 (entry->offset + esize == next->offset)) && 887 (next->needs_copy == entry->needs_copy) && 888 (next->copy_on_write == entry->copy_on_write) && 889 (next->protection == entry->protection) && 890 (next->max_protection == entry->max_protection) && 891 (next->inheritance == entry->inheritance) && 892 (next->is_a_map == FALSE) && 893 (next->is_sub_map == FALSE) && 894 (next->wired_count == 0)) { |
888 if (map->first_free == next) 889 map->first_free = entry; 890 if (map->hint == next) 891 map->hint = entry; 892 vm_map_entry_unlink(map, next); 893 entry->end = next->end; 894 if (next->object.vm_object) 895 vm_object_deallocate(next->object.vm_object); 896 vm_map_entry_dispose(map, next); 897 } 898 } 899} | 895 if (map->first_free == next) 896 map->first_free = entry; 897 if (map->hint == next) 898 map->hint = entry; 899 vm_map_entry_unlink(map, next); 900 entry->end = next->end; 901 if (next->object.vm_object) 902 vm_object_deallocate(next->object.vm_object); 903 vm_map_entry_dispose(map, next); 904 } 905 } 906} |
900 | |
901/* 902 * vm_map_clip_start: [ internal use only ] 903 * 904 * Asserts that the given entry begins at or after 905 * the specified address; if necessary, 906 * it splits the entry into two. 907 */ 908#define vm_map_clip_start(map, entry, startaddr) \ --- 921 unchanged lines hidden (view full) --- 1830 1831 if (map == kmem_map || map == mb_map) 1832 splx(s); 1833 1834 return (result); 1835} 1836 1837/* | 907/* 908 * vm_map_clip_start: [ internal use only ] 909 * 910 * Asserts that the given entry begins at or after 911 * the specified address; if necessary, 912 * it splits the entry into two. 913 */ 914#define vm_map_clip_start(map, entry, startaddr) \ --- 921 unchanged lines hidden (view full) --- 1836 1837 if (map == kmem_map || map == mb_map) 1838 splx(s); 1839 1840 return (result); 1841} 1842 1843/* |
1838 * vm_map_remove_userspace: 1839 * Removes the user portion of the address space. 1840 */ 1841void 1842vm_map_remove_userspace(map) 1843 register vm_map_t map; 1844{ 1845 vm_map_lock(map); 1846 pmap_remove_pages(map->pmap, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS); 1847 vm_map_delete(map, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS); 1848 vm_map_unlock(map); 1849 return; 1850} 1851 1852/* | |
1853 * vm_map_check_protection: 1854 * 1855 * Assert that the target map allows the specified 1856 * privilege on the entire address region given. 1857 * The entire region must be allocated. 1858 */ 1859boolean_t 1860vm_map_check_protection(map, start, end, protection) --- 400 unchanged lines hidden (view full) --- 2261 goto RetryLookup; 2262 } 2263 entry->object.vm_object = vm_object_allocate(OBJT_DEFAULT, 2264 OFF_TO_IDX(entry->end - entry->start)); 2265 entry->offset = 0; 2266 lock_write_to_read(&share_map->lock); 2267 } 2268 | 1844 * vm_map_check_protection: 1845 * 1846 * Assert that the target map allows the specified 1847 * privilege on the entire address region given. 1848 * The entire region must be allocated. 1849 */ 1850boolean_t 1851vm_map_check_protection(map, start, end, protection) --- 400 unchanged lines hidden (view full) --- 2252 goto RetryLookup; 2253 } 2254 entry->object.vm_object = vm_object_allocate(OBJT_DEFAULT, 2255 OFF_TO_IDX(entry->end - entry->start)); 2256 entry->offset = 0; 2257 lock_write_to_read(&share_map->lock); 2258 } 2259 |
2269 default_pager_convert_to_swapq(entry->object.vm_object); 2270 | 2260 if (entry->object.vm_object != NULL) 2261 default_pager_convert_to_swapq(entry->object.vm_object); |
2271 /* 2272 * Return the object/offset from this entry. If the entry was 2273 * copy-on-write or empty, it has been fixed up. 2274 */ 2275 2276 *pindex = OFF_TO_IDX((share_offset - entry->start) + entry->offset); 2277 *object = entry->object.vm_object; 2278 --- 171 unchanged lines hidden --- | 2262 /* 2263 * Return the object/offset from this entry. If the entry was 2264 * copy-on-write or empty, it has been fixed up. 2265 */ 2266 2267 *pindex = OFF_TO_IDX((share_offset - entry->start) + entry->offset); 2268 *object = entry->object.vm_object; 2269 --- 171 unchanged lines hidden --- |