Deleted Added
full compact
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 ---