2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
53 * File: vm/memory_object.c
54 * Author: Michael Wayne Young
56 * External memory management interface control functions.
60 /* THIS code should be removed when the component merge is completed */
61 extern int vnode_pager_workaround
;
64 #include <advisory_pageout.h>
67 * Interface dependencies:
70 #include <mach/std_types.h> /* For pointer_t */
71 #include <mach/mach_types.h>
73 #include <mach/kern_return.h>
74 #include <mach/memory_object.h>
75 #include <mach/memory_object_default.h>
76 #include <mach/memory_object_control_server.h>
77 #include <mach/mach_host_server.h>
78 #include <mach/boolean.h>
79 #include <mach/vm_prot.h>
80 #include <mach/message.h>
82 #include <vm/vm_object.h>
83 #include <vm/vm_fault.h>
85 * Implementation dependencies:
87 #include <string.h> /* For memcpy() */
89 #include <vm/memory_object.h>
90 #include <vm/vm_page.h>
91 #include <vm/vm_pageout.h>
92 #include <vm/pmap.h> /* For pmap_clear_modify */
94 #include <kern/thread.h> /* For current_thread() */
95 #include <kern/host.h>
96 #include <vm/vm_kern.h> /* For kernel_map, vm_move */
97 #include <vm/vm_map.h> /* For vm_map_pageable */
98 #include <ipc/ipc_port.h>
99 #include <ipc/ipc_space.h>
101 #include <kern/misc_protos.h>
104 #include <vm/vm_external.h>
105 #endif /* MACH_PAGEMAP */
108 ipc_port_t memory_manager_default
= IP_NULL
;
109 vm_size_t memory_manager_default_cluster
= 0;
110 decl_mutex_data(,memory_manager_default_lock
)
113 * Forward ref to file-local function:
116 memory_object_update(vm_object_t
, vm_object_offset_t
,
117 vm_size_t
, memory_object_return_t
, int, vm_prot_t
);
121 * Routine: memory_object_should_return_page
124 * Determine whether the given page should be returned,
125 * based on the page's state and on the given return policy.
127 * We should return the page if one of the following is true:
129 * 1. Page is dirty and should_return is not RETURN_NONE.
130 * 2. Page is precious and should_return is RETURN_ALL.
131 * 3. Should_return is RETURN_ANYTHING.
133 * As a side effect, m->dirty will be made consistent
134 * with pmap_is_modified(m), if should_return is not
135 * MEMORY_OBJECT_RETURN_NONE.
138 #define memory_object_should_return_page(m, should_return) \
139 (should_return != MEMORY_OBJECT_RETURN_NONE && \
140 (((m)->dirty || ((m)->dirty = pmap_is_modified((m)->phys_addr))) || \
141 ((m)->precious && (should_return) == MEMORY_OBJECT_RETURN_ALL) || \
142 (should_return) == MEMORY_OBJECT_RETURN_ANYTHING))
144 typedef int memory_object_lock_result_t
;
146 #define MEMORY_OBJECT_LOCK_RESULT_DONE 0
147 #define MEMORY_OBJECT_LOCK_RESULT_MUST_BLOCK 1
148 #define MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN 2
149 #define MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN 3
151 memory_object_lock_result_t
memory_object_lock_page(
153 memory_object_return_t should_return
,
154 boolean_t should_flush
,
158 * Routine: memory_object_lock_page
161 * Perform the appropriate lock operations on the
162 * given page. See the description of
163 * "memory_object_lock_request" for the meanings
166 * Returns an indication that the operation
167 * completed, blocked, or that the page must
170 memory_object_lock_result_t
171 memory_object_lock_page(
173 memory_object_return_t should_return
,
174 boolean_t should_flush
,
177 XPR(XPR_MEMORY_OBJECT
,
178 "m_o_lock_page, page 0x%X rtn %d flush %d prot %d\n",
179 (integer_t
)m
, should_return
, should_flush
, prot
, 0);
182 * If we cannot change access to the page,
183 * either because a mapping is in progress
184 * (busy page) or because a mapping has been
185 * wired, then give up.
188 if (m
->busy
|| m
->cleaning
)
189 return(MEMORY_OBJECT_LOCK_RESULT_MUST_BLOCK
);
192 * Don't worry about pages for which the kernel
193 * does not have any data.
196 if (m
->absent
|| m
->error
|| m
->restart
)
197 return(MEMORY_OBJECT_LOCK_RESULT_DONE
);
199 assert(!m
->fictitious
);
201 if (m
->wire_count
!= 0) {
203 * If no change would take place
204 * anyway, return successfully.
208 * No change to page lock [2 checks] AND
209 * Should not return page
211 * XXX This doesn't handle sending a copy of a wired
212 * XXX page to the pager, but that will require some
213 * XXX significant surgery.
216 (m
->page_lock
== prot
|| prot
== VM_PROT_NO_CHANGE
) &&
217 ! memory_object_should_return_page(m
, should_return
)) {
220 * Restart page unlock requests,
221 * even though no change took place.
222 * [Memory managers may be expecting
223 * to see new requests.]
225 m
->unlock_request
= VM_PROT_NONE
;
228 return(MEMORY_OBJECT_LOCK_RESULT_DONE
);
231 return(MEMORY_OBJECT_LOCK_RESULT_MUST_BLOCK
);
235 * If the page is to be flushed, allow
236 * that to be done as part of the protection.
245 * If we are decreasing permission, do it now;
246 * let the fault handler take care of increases
247 * (pmap_page_protect may not increase protection).
250 if (prot
!= VM_PROT_NO_CHANGE
) {
252 /* code associated with the vestigial
253 * memory_object_data_unlock
255 if ((m
->page_lock
^ prot
) & prot
) {
256 pmap_page_protect(m
->phys_addr
, VM_PROT_ALL
& ~prot
);
259 m
->lock_supplied
= TRUE
;
260 if (prot
!= VM_PROT_NONE
)
266 * Restart any past unlock requests, even if no
267 * change resulted. If the manager explicitly
268 * requested no protection change, then it is assumed
269 * to be remembering past requests.
272 m
->unlock_request
= VM_PROT_NONE
;
278 * Handle page returning.
281 if (memory_object_should_return_page(m
, should_return
)) {
284 * If we weren't planning
285 * to flush the page anyway,
286 * we may need to remove the
287 * page from the pageout
288 * system and from physical
292 vm_page_lock_queues();
293 VM_PAGE_QUEUES_REMOVE(m
);
294 vm_page_unlock_queues();
297 pmap_page_protect(m
->phys_addr
, VM_PROT_NONE
);
300 return(MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN
);
302 return(MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN
);
312 extern boolean_t vm_page_deactivate_hint
;
315 * XXX Make clean but not flush a paging hint,
316 * and deactivate the pages. This is a hack
317 * because it overloads flush/clean with
318 * implementation-dependent meaning. This only
319 * happens to pages that are already clean.
322 if (vm_page_deactivate_hint
&&
323 (should_return
!= MEMORY_OBJECT_RETURN_NONE
)) {
324 vm_page_lock_queues();
325 vm_page_deactivate(m
);
326 vm_page_unlock_queues();
330 return(MEMORY_OBJECT_LOCK_RESULT_DONE
);
332 #define LIST_REQ_PAGEOUT_PAGES(object, data_cnt, action, po) \
336 register vm_page_t hp; \
338 vm_object_unlock(object); \
340 if(((rpc_subsystem_t)pager_mux_hash_lookup(object->pager)) == \
341 ((rpc_subsystem_t) &vnode_pager_workaround)) { \
342 (void) vnode_pager_data_return(object->pager, \
343 object->pager_request, \
347 (action == MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN), \
350 (void) memory_object_data_return(object->pager, \
351 object->pager_request, \
355 (action == MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN), \
359 vm_object_lock(object); \
364 #define PAGEOUT_PAGES(object, new_object, new_offset, action, po) \
367 vm_map_copy_t copy; \
369 register vm_page_t hp; \
371 vm_object_unlock(object); \
373 (void) vm_map_copyin_object(new_object, 0, new_offset, ©); \
375 if(((rpc_subsystem_t)pager_mux_hash_lookup(object->pager)) == \
376 ((rpc_subsystem_t) &vnode_pager_workaround)) { \
377 (void) vnode_pager_data_return(object->pager, \
378 object->pager_request, \
382 (action == MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN), \
385 (void) memory_object_data_return(object->pager, \
386 object->pager_request, \
390 (action == MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN), \
394 vm_object_lock(object); \
396 for (i = 0; i < atop(new_offset); i++) { \
397 hp = holding_pages[i]; \
398 if (hp != VM_PAGE_NULL) { \
399 vm_object_paging_end(object); \
404 new_object = VM_OBJECT_NULL; \
407 #define PAGEOUT_PAGES(object, new_object, new_offset, action, po) \
410 vm_map_copy_t copy; \
412 register vm_page_t hp; \
414 vm_object_unlock(object); \
416 (void) vm_map_copyin_object(new_object, 0, new_offset, ©); \
418 (void) memory_object_data_return( \
420 object->pager_request, \
424 (action == MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN), \
427 vm_object_lock(object); \
429 for (i = 0; i < atop(new_offset); i++) { \
430 hp = holding_pages[i]; \
431 if (hp != VM_PAGE_NULL) { \
432 vm_object_paging_end(object); \
437 new_object = VM_OBJECT_NULL; \
442 * Routine: memory_object_lock_request [user interface]
445 * Control use of the data associated with the given
446 * memory object. For each page in the given range,
447 * perform the following operations, in order:
448 * 1) restrict access to the page (disallow
449 * forms specified by "prot");
450 * 2) return data to the manager (if "should_return"
451 * is RETURN_DIRTY and the page is dirty, or
452 * "should_return" is RETURN_ALL and the page
453 * is either dirty or precious); and,
454 * 3) flush the cached copy (if "should_flush"
456 * The set of pages is defined by a starting offset
457 * ("offset") and size ("size"). Only pages with the
458 * same page alignment as the starting offset are
461 * A single acknowledgement is sent (to the "reply_to"
462 * port) when these actions are complete. If successful,
463 * the naked send right for reply_to is consumed.
467 memory_object_lock_request(
468 register vm_object_t object
,
469 register vm_object_offset_t offset
,
470 register vm_object_size_t size
,
471 memory_object_return_t should_return
,
475 mach_msg_type_name_t reply_to_type
)
477 vm_object_offset_t original_offset
= offset
;
478 boolean_t should_flush
=flags
& MEMORY_OBJECT_DATA_FLUSH
;
480 XPR(XPR_MEMORY_OBJECT
,
481 "m_o_lock_request, obj 0x%X off 0x%X size 0x%X flags %X prot %X\n",
482 (integer_t
)object
, offset
, size
,
483 (((should_return
&1)<<1)|should_flush
), prot
);
486 * Check for bogus arguments.
488 if (object
== VM_OBJECT_NULL
)
489 return (KERN_INVALID_ARGUMENT
);
491 if ((prot
& ~VM_PROT_ALL
) != 0 && prot
!= VM_PROT_NO_CHANGE
) {
492 vm_object_deallocate(object
);
493 return (KERN_INVALID_ARGUMENT
);
496 size
= round_page(size
);
499 * Lock the object, and acquire a paging reference to
500 * prevent the memory_object and control ports from
504 vm_object_lock(object
);
505 vm_object_paging_begin(object
);
506 offset
-= object
->paging_offset
;
508 (void)memory_object_update(object
,
509 offset
, size
, should_return
, flags
, prot
);
511 if (IP_VALID(reply_to
)) {
512 vm_object_unlock(object
);
514 /* consumes our naked send-once/send right for reply_to */
515 (void) memory_object_lock_completed(reply_to
, reply_to_type
,
516 object
->pager_request
, original_offset
, size
);
518 vm_object_lock(object
);
521 vm_object_paging_end(object
);
522 vm_object_unlock(object
);
523 vm_object_deallocate(object
);
525 return (KERN_SUCCESS
);
529 * Routine: memory_object_sync
531 * Kernel internal function to synch out pages in a given
532 * range within an object to its memory manager. Much the
533 * same as memory_object_lock_request but page protection
536 * If the should_flush and should_return flags are true pages
537 * are flushed, that is dirty & precious pages are written to
538 * the memory manager and then discarded. If should_return
539 * is false, only precious pages are returned to the memory
542 * If should flush is false and should_return true, the memory
543 * manager's copy of the pages is updated. If should_return
544 * is also false, only the precious pages are updated. This
545 * last option is of limited utility.
548 * FALSE if no pages were returned to the pager
555 vm_object_offset_t offset
,
556 vm_object_size_t size
,
557 boolean_t should_flush
,
558 boolean_t should_return
)
562 XPR(XPR_MEMORY_OBJECT
,
563 "m_o_sync, object 0x%X, offset 0x%X size 0x%x flush %d rtn %d\n",
564 (integer_t
)object
, offset
, size
, should_flush
, should_return
);
567 * Lock the object, and acquire a paging reference to
568 * prevent the memory_object and control ports from
571 vm_object_lock(object
);
572 vm_object_paging_begin(object
);
574 rv
= memory_object_update(object
, offset
, size
,
576 MEMORY_OBJECT_RETURN_ALL
:
577 MEMORY_OBJECT_RETURN_NONE
,
579 MEMORY_OBJECT_DATA_FLUSH
: 0,
583 vm_object_paging_end(object
);
584 vm_object_unlock(object
);
589 * Routine: memory_object_update
591 * Work function for m_o_lock_request(), m_o_sync().
593 * Called with object locked and paging ref taken.
596 memory_object_update(
597 register vm_object_t object
,
598 register vm_object_offset_t offset
,
599 register vm_size_t size
,
600 memory_object_return_t should_return
,
604 register vm_page_t m
;
605 vm_page_t holding_page
;
606 vm_size_t original_size
= size
;
607 vm_object_offset_t paging_offset
= 0;
608 vm_object_t copy_object
;
609 vm_size_t data_cnt
= 0;
610 vm_object_offset_t last_offset
= offset
;
611 memory_object_lock_result_t page_lock_result
;
612 memory_object_lock_result_t pageout_action
;
613 boolean_t data_returned
= FALSE
;
614 boolean_t update_cow
;
615 boolean_t should_flush
= flags
& MEMORY_OBJECT_DATA_FLUSH
;
617 boolean_t pending_pageout
= FALSE
;
621 * To avoid blocking while scanning for pages, save
622 * dirty pages to be cleaned all at once.
624 * XXXO A similar strategy could be used to limit the
625 * number of times that a scan must be restarted for
626 * other reasons. Those pages that would require blocking
627 * could be temporarily collected in another list, or
628 * their offsets could be recorded in a small array.
632 * XXX NOTE: May want to consider converting this to a page list
633 * XXX vm_map_copy interface. Need to understand object
634 * XXX coalescing implications before doing so.
637 update_cow
= ((flags
& MEMORY_OBJECT_DATA_FLUSH
)
638 && (!(flags
& MEMORY_OBJECT_DATA_NO_CHANGE
) &&
639 !(flags
& MEMORY_OBJECT_DATA_PURGE
)))
640 || (flags
& MEMORY_OBJECT_COPY_SYNC
);
643 if((((copy_object
= object
->copy
) != NULL
) && update_cow
) ||
644 (flags
& MEMORY_OBJECT_DATA_SYNC
)) {
647 vm_object_offset_t copy_offset
;
651 kern_return_t error
= 0;
653 if(copy_object
!= NULL
) {
654 /* translate offset with respect to shadow's offset */
655 copy_offset
= (offset
>= copy_object
->shadow_offset
)?
656 offset
- copy_object
->shadow_offset
:
657 (vm_object_offset_t
) 0;
658 if(copy_offset
> copy_object
->size
)
659 copy_offset
= copy_object
->size
;
661 /* clip size with respect to shadow offset */
662 copy_size
= (offset
>= copy_object
->shadow_offset
) ?
663 size
: size
- (copy_object
->shadow_offset
- offset
);
668 copy_size
= ((copy_offset
+ copy_size
)
669 <= copy_object
->size
) ?
670 copy_size
: copy_object
->size
- copy_offset
;
672 /* check for a copy_offset which is beyond the end of */
673 /* the copy_object */
679 vm_object_unlock(object
);
680 vm_object_lock(copy_object
);
682 copy_object
= object
;
684 copy_size
= offset
+ size
;
685 copy_offset
= offset
;
688 vm_object_paging_begin(copy_object
);
689 for (i
=copy_offset
; i
<copy_size
; i
+=PAGE_SIZE
) {
690 RETRY_COW_OF_LOCK_REQUEST
:
691 prot
= VM_PROT_WRITE
|VM_PROT_READ
;
692 switch (vm_fault_page(copy_object
, i
,
693 VM_PROT_WRITE
|VM_PROT_READ
,
697 copy_offset
+copy_size
,
698 VM_BEHAVIOR_SEQUENTIAL
,
707 case VM_FAULT_SUCCESS
:
710 page
->object
, top_page
);
711 PAGE_WAKEUP_DONE(page
);
712 vm_page_lock_queues();
713 if (!page
->active
&& !page
->inactive
)
714 vm_page_activate(page
);
715 vm_page_unlock_queues();
716 vm_object_lock(copy_object
);
717 vm_object_paging_begin(copy_object
);
719 PAGE_WAKEUP_DONE(page
);
720 vm_page_lock_queues();
721 if (!page
->active
&& !page
->inactive
)
722 vm_page_activate(page
);
723 vm_page_unlock_queues();
727 prot
= VM_PROT_WRITE
|VM_PROT_READ
;
728 vm_object_lock(copy_object
);
729 vm_object_paging_begin(copy_object
);
730 goto RETRY_COW_OF_LOCK_REQUEST
;
731 case VM_FAULT_INTERRUPTED
:
732 prot
= VM_PROT_WRITE
|VM_PROT_READ
;
733 vm_object_lock(copy_object
);
734 vm_object_paging_begin(copy_object
);
735 goto RETRY_COW_OF_LOCK_REQUEST
;
736 case VM_FAULT_MEMORY_SHORTAGE
:
738 prot
= VM_PROT_WRITE
|VM_PROT_READ
;
739 vm_object_lock(copy_object
);
740 vm_object_paging_begin(copy_object
);
741 goto RETRY_COW_OF_LOCK_REQUEST
;
742 case VM_FAULT_FICTITIOUS_SHORTAGE
:
743 vm_page_more_fictitious();
744 prot
= VM_PROT_WRITE
|VM_PROT_READ
;
745 vm_object_lock(copy_object
);
746 vm_object_paging_begin(copy_object
);
747 goto RETRY_COW_OF_LOCK_REQUEST
;
748 case VM_FAULT_MEMORY_ERROR
:
749 vm_object_lock(object
);
750 goto BYPASS_COW_COPYIN
;
754 vm_object_paging_end(copy_object
);
755 if(copy_object
!= object
) {
756 vm_object_unlock(copy_object
);
757 vm_object_lock(object
);
760 if((flags
& (MEMORY_OBJECT_DATA_SYNC
| MEMORY_OBJECT_COPY_SYNC
))) {
763 if(((copy_object
= object
->copy
) != NULL
) &&
764 (flags
& MEMORY_OBJECT_DATA_PURGE
)) {
765 copy_object
->shadow_severed
= TRUE
;
766 copy_object
->shadowed
= FALSE
;
767 copy_object
->shadow
= NULL
;
768 /* delete the ref the COW was holding on the target object */
769 vm_object_deallocate(object
);
775 size
-= PAGE_SIZE
, offset
+= PAGE_SIZE_64
)
778 * Limit the number of pages to be cleaned at once.
780 if (pending_pageout
&&
781 data_cnt
>= PAGE_SIZE
* DATA_WRITE_MAX
)
783 LIST_REQ_PAGEOUT_PAGES(object
, data_cnt
,
784 pageout_action
, paging_offset
);
786 pending_pageout
= FALSE
;
789 while ((m
= vm_page_lookup(object
, offset
)) != VM_PAGE_NULL
) {
790 page_lock_result
= memory_object_lock_page(m
, should_return
,
793 XPR(XPR_MEMORY_OBJECT
,
794 "m_o_update: lock_page, obj 0x%X offset 0x%X result %d\n",
795 (integer_t
)object
, offset
, page_lock_result
, 0, 0);
797 switch (page_lock_result
)
799 case MEMORY_OBJECT_LOCK_RESULT_DONE
:
801 * End of a cluster of dirty pages.
803 if(pending_pageout
) {
804 LIST_REQ_PAGEOUT_PAGES(object
,
805 data_cnt
, pageout_action
,
808 pending_pageout
= FALSE
;
813 case MEMORY_OBJECT_LOCK_RESULT_MUST_BLOCK
:
815 * Since it is necessary to block,
816 * clean any dirty pages now.
818 if(pending_pageout
) {
819 LIST_REQ_PAGEOUT_PAGES(object
,
820 data_cnt
, pageout_action
,
822 pending_pageout
= FALSE
;
827 PAGE_ASSERT_WAIT(m
, THREAD_UNINT
);
828 vm_object_unlock(object
);
829 thread_block((void (*)(void))0);
830 vm_object_lock(object
);
833 case MEMORY_OBJECT_LOCK_RESULT_MUST_CLEAN
:
834 case MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN
:
836 * The clean and return cases are similar.
841 * if this would form a discontiguous block,
842 * clean the old pages and start anew.
847 * Mark the page busy since we unlock the
851 if (pending_pageout
&&
852 (last_offset
!= offset
||
853 pageout_action
!= page_lock_result
)) {
854 LIST_REQ_PAGEOUT_PAGES(object
,
855 data_cnt
, pageout_action
,
857 pending_pageout
= FALSE
;
861 holding_page
= VM_PAGE_NULL
;
863 PAGE_ASSERT_WAIT(m
, THREAD_UNINT
);
864 vm_object_unlock(object
);
865 thread_block((void (*)(void))0);
868 if(!pending_pageout
) {
869 pending_pageout
= TRUE
;
870 pageout_action
= page_lock_result
;
871 paging_offset
= offset
;
874 vm_page_lock_queues();
875 m
->list_req_pending
= TRUE
;
880 vm_page_unlock_queues();
883 * Clean but do not flush
885 vm_page_lock_queues();
886 m
->list_req_pending
= TRUE
;
888 vm_page_unlock_queues();
891 vm_object_unlock(object
);
894 data_cnt
+= PAGE_SIZE
;
895 last_offset
= offset
+ PAGE_SIZE_64
;
896 data_returned
= TRUE
;
898 vm_object_lock(object
);
906 * We have completed the scan for applicable pages.
907 * Clean any pages that have been saved.
910 if (new_object
!= VM_OBJECT_NULL
) {
911 PAGEOUT_PAGES(object
, new_object
, new_offset
, pageout_action
,
915 if (pending_pageout
) {
916 LIST_REQ_PAGEOUT_PAGES(object
,
917 data_cnt
, pageout_action
, paging_offset
);
920 return (data_returned
);
924 * Routine: memory_object_synchronize_completed [user interface]
926 * Tell kernel that previously synchronized data
927 * (memory_object_synchronize) has been queue or placed on the
930 * Note: there may be multiple synchronize requests for a given
931 * memory object outstanding but they will not overlap.
935 memory_object_synchronize_completed(
937 vm_object_offset_t offset
,
942 XPR(XPR_MEMORY_OBJECT
,
943 "m_o_sync_completed, object 0x%X, offset 0x%X length 0x%X\n",
944 (integer_t
)object
, offset
, length
, 0, 0);
947 * Look for bogus arguments
950 if (object
== VM_OBJECT_NULL
) {
951 return KERN_INVALID_ARGUMENT
;
954 vm_object_lock(object
);
957 * search for sync request structure
959 queue_iterate(&object
->msr_q
, msr
, msync_req_t
, msr_q
) {
960 if (msr
->offset
== offset
&& msr
->length
== length
) {
961 queue_remove(&object
->msr_q
, msr
, msync_req_t
, msr_q
);
966 if (queue_end(&object
->msr_q
, (queue_entry_t
)msr
)) {
967 vm_object_unlock(object
);
968 vm_object_deallocate(object
);
969 return KERN_INVALID_ARGUMENT
;
973 vm_object_unlock(object
);
974 msr
->flag
= VM_MSYNC_DONE
;
976 thread_wakeup((event_t
) msr
);
977 vm_object_deallocate(object
);
980 }/* memory_object_synchronize_completed */
983 memory_object_set_attributes_common(
986 memory_object_copy_strategy_t copy_strategy
,
988 vm_size_t cluster_size
,
989 boolean_t silent_overwrite
,
990 boolean_t advisory_pageout
)
992 boolean_t object_became_ready
;
994 XPR(XPR_MEMORY_OBJECT
,
995 "m_o_set_attr_com, object 0x%X flg %x strat %d\n",
996 (integer_t
)object
, (may_cache
&1)|((temporary
&1)<1), copy_strategy
, 0, 0);
998 if (object
== VM_OBJECT_NULL
)
999 return(KERN_INVALID_ARGUMENT
);
1002 * Verify the attributes of importance
1005 switch(copy_strategy
) {
1006 case MEMORY_OBJECT_COPY_NONE
:
1007 case MEMORY_OBJECT_COPY_DELAY
:
1010 vm_object_deallocate(object
);
1011 return(KERN_INVALID_ARGUMENT
);
1014 #if !ADVISORY_PAGEOUT
1015 if (silent_overwrite
|| advisory_pageout
) {
1016 vm_object_deallocate(object
);
1017 return(KERN_INVALID_ARGUMENT
);
1019 #endif /* !ADVISORY_PAGEOUT */
1024 if (cluster_size
!= 0) {
1025 int pages_per_cluster
;
1026 pages_per_cluster
= atop(cluster_size
);
1028 * Cluster size must be integral multiple of page size,
1029 * and be a power of 2 number of pages.
1031 if ((cluster_size
& (PAGE_SIZE
-1)) ||
1032 ((pages_per_cluster
-1) & pages_per_cluster
)) {
1033 vm_object_deallocate(object
);
1034 return KERN_INVALID_ARGUMENT
;
1038 vm_object_lock(object
);
1041 * Copy the attributes
1043 assert(!object
->internal
);
1044 object_became_ready
= !object
->pager_ready
;
1045 object
->copy_strategy
= copy_strategy
;
1046 object
->can_persist
= may_cache
;
1047 object
->temporary
= temporary
;
1048 object
->silent_overwrite
= silent_overwrite
;
1049 object
->advisory_pageout
= advisory_pageout
;
1050 if (cluster_size
== 0)
1051 cluster_size
= PAGE_SIZE
;
1052 object
->cluster_size
= cluster_size
;
1054 assert(cluster_size
>= PAGE_SIZE
&&
1055 cluster_size
% PAGE_SIZE
== 0);
1058 * Wake up anyone waiting for the ready attribute
1059 * to become asserted.
1062 if (object_became_ready
) {
1063 object
->pager_ready
= TRUE
;
1064 vm_object_wakeup(object
, VM_OBJECT_EVENT_PAGER_READY
);
1067 vm_object_unlock(object
);
1069 vm_object_deallocate(object
);
1071 return(KERN_SUCCESS
);
1075 * Set the memory object attribute as provided.
1077 * XXX This routine cannot be completed until the vm_msync, clean
1078 * in place, and cluster work is completed. See ifdef notyet
1079 * below and note that memory_object_set_attributes_common()
1080 * may have to be expanded.
1083 memory_object_change_attributes(
1085 memory_object_flavor_t flavor
,
1086 memory_object_info_t attributes
,
1087 mach_msg_type_number_t count
,
1088 ipc_port_t reply_to
,
1089 mach_msg_type_name_t reply_to_type
)
1091 kern_return_t result
= KERN_SUCCESS
;
1092 boolean_t temporary
;
1093 boolean_t may_cache
;
1094 boolean_t invalidate
;
1095 vm_size_t cluster_size
;
1096 memory_object_copy_strategy_t copy_strategy
;
1097 boolean_t silent_overwrite
;
1098 boolean_t advisory_pageout
;
1100 if (object
== VM_OBJECT_NULL
)
1101 return(KERN_INVALID_ARGUMENT
);
1103 vm_object_lock(object
);
1104 temporary
= object
->temporary
;
1105 may_cache
= object
->can_persist
;
1106 copy_strategy
= object
->copy_strategy
;
1107 silent_overwrite
= object
->silent_overwrite
;
1108 advisory_pageout
= object
->advisory_pageout
;
1110 invalidate
= object
->invalidate
;
1112 cluster_size
= object
->cluster_size
;
1113 vm_object_unlock(object
);
1116 case OLD_MEMORY_OBJECT_BEHAVIOR_INFO
:
1118 old_memory_object_behave_info_t behave
;
1120 if (count
!= OLD_MEMORY_OBJECT_BEHAVE_INFO_COUNT
) {
1121 result
= KERN_INVALID_ARGUMENT
;
1125 behave
= (old_memory_object_behave_info_t
) attributes
;
1127 temporary
= behave
->temporary
;
1128 invalidate
= behave
->invalidate
;
1129 copy_strategy
= behave
->copy_strategy
;
1134 case MEMORY_OBJECT_BEHAVIOR_INFO
:
1136 memory_object_behave_info_t behave
;
1138 if (count
!= MEMORY_OBJECT_BEHAVE_INFO_COUNT
) {
1139 result
= KERN_INVALID_ARGUMENT
;
1143 behave
= (memory_object_behave_info_t
) attributes
;
1145 temporary
= behave
->temporary
;
1146 invalidate
= behave
->invalidate
;
1147 copy_strategy
= behave
->copy_strategy
;
1148 silent_overwrite
= behave
->silent_overwrite
;
1149 advisory_pageout
= behave
->advisory_pageout
;
1153 case MEMORY_OBJECT_PERFORMANCE_INFO
:
1155 memory_object_perf_info_t perf
;
1157 if (count
!= MEMORY_OBJECT_PERF_INFO_COUNT
) {
1158 result
= KERN_INVALID_ARGUMENT
;
1162 perf
= (memory_object_perf_info_t
) attributes
;
1164 may_cache
= perf
->may_cache
;
1165 cluster_size
= round_page(perf
->cluster_size
);
1170 case OLD_MEMORY_OBJECT_ATTRIBUTE_INFO
:
1172 old_memory_object_attr_info_t attr
;
1174 if (count
!= OLD_MEMORY_OBJECT_ATTR_INFO_COUNT
) {
1175 result
= KERN_INVALID_ARGUMENT
;
1179 attr
= (old_memory_object_attr_info_t
) attributes
;
1181 may_cache
= attr
->may_cache
;
1182 copy_strategy
= attr
->copy_strategy
;
1183 cluster_size
= page_size
;
1188 case MEMORY_OBJECT_ATTRIBUTE_INFO
:
1190 memory_object_attr_info_t attr
;
1192 if (count
!= MEMORY_OBJECT_ATTR_INFO_COUNT
) {
1193 result
= KERN_INVALID_ARGUMENT
;
1197 attr
= (memory_object_attr_info_t
) attributes
;
1199 copy_strategy
= attr
->copy_strategy
;
1200 may_cache
= attr
->may_cache_object
;
1201 cluster_size
= attr
->cluster_size
;
1202 temporary
= attr
->temporary
;
1208 result
= KERN_INVALID_ARGUMENT
;
1212 if (result
!= KERN_SUCCESS
) {
1213 vm_object_deallocate(object
);
1217 if (copy_strategy
== MEMORY_OBJECT_COPY_TEMPORARY
) {
1218 copy_strategy
= MEMORY_OBJECT_COPY_DELAY
;
1225 * Do the work and throw away our object reference. It
1226 * is important that the object reference be deallocated
1227 * BEFORE sending the reply. The whole point of the reply
1228 * is that it shows up after the terminate message that
1229 * may be generated by setting the object uncacheable.
1231 * XXX may_cache may become a tri-valued variable to handle
1232 * XXX uncache if not in use.
1234 result
= memory_object_set_attributes_common(object
,
1242 if (IP_VALID(reply_to
)) {
1243 /* consumes our naked send-once/send right for reply_to */
1244 (void) memory_object_change_completed(reply_to
, reply_to_type
,
1246 object
->pager_request
: PAGER_REQUEST_NULL
,
1254 memory_object_get_attributes(
1256 memory_object_flavor_t flavor
,
1257 memory_object_info_t attributes
, /* pointer to OUT array */
1258 mach_msg_type_number_t
*count
) /* IN/OUT */
1260 kern_return_t ret
= KERN_SUCCESS
;
1262 if (object
== VM_OBJECT_NULL
)
1263 return(KERN_INVALID_ARGUMENT
);
1265 vm_object_lock(object
);
1268 case OLD_MEMORY_OBJECT_BEHAVIOR_INFO
:
1270 old_memory_object_behave_info_t behave
;
1272 if (*count
< OLD_MEMORY_OBJECT_BEHAVE_INFO_COUNT
) {
1273 ret
= KERN_INVALID_ARGUMENT
;
1277 behave
= (old_memory_object_behave_info_t
) attributes
;
1278 behave
->copy_strategy
= object
->copy_strategy
;
1279 behave
->temporary
= object
->temporary
;
1280 #if notyet /* remove when vm_msync complies and clean in place fini */
1281 behave
->invalidate
= object
->invalidate
;
1283 behave
->invalidate
= FALSE
;
1286 *count
= OLD_MEMORY_OBJECT_BEHAVE_INFO_COUNT
;
1290 case MEMORY_OBJECT_BEHAVIOR_INFO
:
1292 memory_object_behave_info_t behave
;
1294 if (*count
< MEMORY_OBJECT_BEHAVE_INFO_COUNT
) {
1295 ret
= KERN_INVALID_ARGUMENT
;
1299 behave
= (memory_object_behave_info_t
) attributes
;
1300 behave
->copy_strategy
= object
->copy_strategy
;
1301 behave
->temporary
= object
->temporary
;
1302 #if notyet /* remove when vm_msync complies and clean in place fini */
1303 behave
->invalidate
= object
->invalidate
;
1305 behave
->invalidate
= FALSE
;
1307 behave
->advisory_pageout
= object
->advisory_pageout
;
1308 behave
->silent_overwrite
= object
->silent_overwrite
;
1309 *count
= MEMORY_OBJECT_BEHAVE_INFO_COUNT
;
1313 case MEMORY_OBJECT_PERFORMANCE_INFO
:
1315 memory_object_perf_info_t perf
;
1317 if (*count
< MEMORY_OBJECT_PERF_INFO_COUNT
) {
1318 ret
= KERN_INVALID_ARGUMENT
;
1322 perf
= (memory_object_perf_info_t
) attributes
;
1323 perf
->cluster_size
= object
->cluster_size
;
1324 perf
->may_cache
= object
->can_persist
;
1326 *count
= MEMORY_OBJECT_PERF_INFO_COUNT
;
1330 case OLD_MEMORY_OBJECT_ATTRIBUTE_INFO
:
1332 old_memory_object_attr_info_t attr
;
1334 if (*count
< OLD_MEMORY_OBJECT_ATTR_INFO_COUNT
) {
1335 ret
= KERN_INVALID_ARGUMENT
;
1339 attr
= (old_memory_object_attr_info_t
) attributes
;
1340 attr
->may_cache
= object
->can_persist
;
1341 attr
->copy_strategy
= object
->copy_strategy
;
1343 *count
= OLD_MEMORY_OBJECT_ATTR_INFO_COUNT
;
1347 case MEMORY_OBJECT_ATTRIBUTE_INFO
:
1349 memory_object_attr_info_t attr
;
1351 if (*count
< MEMORY_OBJECT_ATTR_INFO_COUNT
) {
1352 ret
= KERN_INVALID_ARGUMENT
;
1356 attr
= (memory_object_attr_info_t
) attributes
;
1357 attr
->copy_strategy
= object
->copy_strategy
;
1358 attr
->cluster_size
= object
->cluster_size
;
1359 attr
->may_cache_object
= object
->can_persist
;
1360 attr
->temporary
= object
->temporary
;
1362 *count
= MEMORY_OBJECT_ATTR_INFO_COUNT
;
1367 ret
= KERN_INVALID_ARGUMENT
;
1371 vm_object_unlock(object
);
1373 vm_object_deallocate(object
);
1378 int vm_stat_discard_cleared_reply
= 0;
1379 int vm_stat_discard_cleared_unset
= 0;
1380 int vm_stat_discard_cleared_too_late
= 0;
1384 * vm_set_default_memory_manager():
1388 vm_set_default_memory_manager(
1390 ipc_port_t
*default_manager
)
1392 return(host_default_memory_manager(host_priv_self(), default_manager
, 4*PAGE_SIZE
));
1396 * Routine: host_default_memory_manager
1398 * set/get the default memory manager port and default cluster
1401 * If successful, consumes the supplied naked send right.
1404 host_default_memory_manager(
1405 host_priv_t host_priv
,
1406 ipc_port_t
*default_manager
,
1407 vm_size_t cluster_size
)
1409 ipc_port_t current_manager
;
1410 ipc_port_t new_manager
;
1411 ipc_port_t returned_manager
;
1413 if (host_priv
== HOST_PRIV_NULL
)
1414 return(KERN_INVALID_HOST
);
1416 assert(host_priv
== &realhost
);
1418 new_manager
= *default_manager
;
1419 mutex_lock(&memory_manager_default_lock
);
1420 current_manager
= memory_manager_default
;
1422 if (new_manager
== IP_NULL
) {
1424 * Retrieve the current value.
1427 returned_manager
= ipc_port_copy_send(current_manager
);
1430 * Retrieve the current value,
1431 * and replace it with the supplied value.
1432 * We consume the supplied naked send right.
1435 returned_manager
= current_manager
;
1436 memory_manager_default
= new_manager
;
1437 if (cluster_size
% PAGE_SIZE
!= 0) {
1439 mutex_unlock(&memory_manager_default_lock
);
1440 return KERN_INVALID_ARGUMENT
;
1442 cluster_size
= round_page(cluster_size
);
1445 memory_manager_default_cluster
= cluster_size
;
1448 * In case anyone's been waiting for a memory
1449 * manager to be established, wake them up.
1452 thread_wakeup((event_t
) &memory_manager_default
);
1455 mutex_unlock(&memory_manager_default_lock
);
1457 *default_manager
= returned_manager
;
1458 return(KERN_SUCCESS
);
1462 * Routine: memory_manager_default_reference
1464 * Returns a naked send right for the default
1465 * memory manager. The returned right is always
1466 * valid (not IP_NULL or IP_DEAD).
1470 memory_manager_default_reference(
1471 vm_size_t
*cluster_size
)
1473 ipc_port_t current_manager
;
1475 mutex_lock(&memory_manager_default_lock
);
1477 while (current_manager
= ipc_port_copy_send(memory_manager_default
),
1478 !IP_VALID(current_manager
)) {
1479 thread_sleep_mutex((event_t
) &memory_manager_default
,
1480 &memory_manager_default_lock
, THREAD_UNINT
);
1481 mutex_lock(&memory_manager_default_lock
);
1483 *cluster_size
= memory_manager_default_cluster
;
1485 mutex_unlock(&memory_manager_default_lock
);
1487 return current_manager
;
1491 * Routine: memory_manager_default_port
1493 * Returns true if the receiver for the port
1494 * is the default memory manager.
1496 * This is a hack to let ds_read_done
1497 * know when it should keep memory wired.
1501 memory_manager_default_port(
1507 mutex_lock(&memory_manager_default_lock
);
1508 current
= memory_manager_default
;
1509 if (IP_VALID(current
)) {
1511 * There is no point in bothering to lock
1512 * both ports, which would be painful to do.
1513 * If the receive rights are moving around,
1514 * we might be inaccurate.
1517 result
= port
->ip_receiver
== current
->ip_receiver
;
1520 mutex_unlock(&memory_manager_default_lock
);
1526 * Routine: memory_manager_default_check
1529 * Check whether a default memory manager has been set
1530 * up yet, or not. Returns KERN_SUCCESS if dmm exists,
1531 * and KERN_FAILURE if dmm does not exist.
1533 * If there is no default memory manager, log an error,
1534 * but only the first time.
1538 memory_manager_default_check(void)
1542 mutex_lock(&memory_manager_default_lock
);
1543 current
= memory_manager_default
;
1544 if (!IP_VALID(current
)) {
1545 static boolean_t logged
; /* initialized to 0 */
1546 boolean_t complain
= !logged
;
1548 mutex_unlock(&memory_manager_default_lock
);
1550 printf("Warning: No default memory manager\n");
1551 return(KERN_FAILURE
);
1553 mutex_unlock(&memory_manager_default_lock
);
1554 return(KERN_SUCCESS
);
1559 memory_manager_default_init(void)
1561 memory_manager_default
= IP_NULL
;
1562 mutex_init(&memory_manager_default_lock
, ETAP_VM_MEMMAN
);
1567 memory_object_deactivate_pages(
1569 vm_object_offset_t offset
,
1570 vm_object_size_t size
,
1571 boolean_t kill_page
)
1573 vm_object_t orig_object
;
1574 int pages_moved
= 0;
1575 int pages_found
= 0;
1578 * entered with object lock held, acquire a paging reference to
1579 * prevent the memory_object and control ports from
1582 orig_object
= object
;
1585 register vm_page_t m
;
1586 vm_object_offset_t toffset
;
1587 vm_object_size_t tsize
;
1589 vm_object_paging_begin(object
);
1590 vm_page_lock_queues();
1592 for (tsize
= size
, toffset
= offset
; tsize
; tsize
-= PAGE_SIZE
, toffset
+= PAGE_SIZE
) {
1594 if ((m
= vm_page_lookup(object
, toffset
)) != VM_PAGE_NULL
) {
1598 if ((m
->wire_count
== 0) && (!m
->private) && (!m
->gobbled
) && (!m
->busy
)) {
1600 m
->reference
= FALSE
;
1601 pmap_clear_reference(m
->phys_addr
);
1603 if ((kill_page
) && (object
->internal
)) {
1604 m
->precious
= FALSE
;
1606 pmap_clear_modify(m
->phys_addr
);
1607 vm_external_state_clr(object
->existence_map
, offset
);
1609 VM_PAGE_QUEUES_REMOVE(m
);
1611 queue_enter_first(&vm_page_queue_inactive
, m
, vm_page_t
, pageq
);
1615 vm_page_inactive_count
++;
1621 vm_page_unlock_queues();
1622 vm_object_paging_end(object
);
1624 if (object
->shadow
) {
1625 vm_object_t tmp_object
;
1629 offset
+= object
->shadow_offset
;
1631 tmp_object
= object
->shadow
;
1632 vm_object_lock(tmp_object
);
1634 if (object
!= orig_object
)
1635 vm_object_unlock(object
);
1636 object
= tmp_object
;
1640 if (object
!= orig_object
)
1641 vm_object_unlock(object
);
1644 /* Allow manipulation of individual page state. This is actually part of */
1645 /* the UPL regimen but takes place on the object rather than on a UPL */
1648 memory_object_page_op(
1650 vm_object_offset_t offset
,
1652 vm_offset_t
*phys_entry
,
1657 vm_object_lock(object
);
1660 if((dst_page
= vm_page_lookup(object
,offset
)) == VM_PAGE_NULL
) {
1661 vm_object_unlock(object
);
1662 return KERN_FAILURE
;
1665 /* Sync up on getting the busy bit */
1666 if((dst_page
->busy
|| dst_page
->cleaning
) &&
1667 (((ops
& UPL_POP_SET
) && (ops
& UPL_POP_BUSY
)) || (ops
& UPL_POP_DUMP
))) {
1668 /* someone else is playing with the page, we will */
1670 PAGE_ASSERT_WAIT(dst_page
, THREAD_UNINT
);
1671 vm_object_unlock(object
);
1672 thread_block((void(*)(void))0);
1673 vm_object_lock(object
);
1677 if (ops
& UPL_POP_DUMP
) {
1678 vm_page_lock_queues();
1679 vm_page_free(dst_page
);
1680 vm_page_unlock_queues();
1687 /* Get the condition of flags before requested ops */
1688 /* are undertaken */
1690 if(dst_page
->dirty
) *flags
|= UPL_POP_DIRTY
;
1691 if(dst_page
->pageout
) *flags
|= UPL_POP_PAGEOUT
;
1692 if(dst_page
->precious
) *flags
|= UPL_POP_PRECIOUS
;
1693 if(dst_page
->absent
) *flags
|= UPL_POP_ABSENT
;
1694 if(dst_page
->busy
) *flags
|= UPL_POP_BUSY
;
1697 *phys_entry
= dst_page
->phys_addr
;
1699 /* The caller should have made a call either contingent with */
1700 /* or prior to this call to set UPL_POP_BUSY */
1701 if(ops
& UPL_POP_SET
) {
1702 /* The protection granted with this assert will */
1703 /* not be complete. If the caller violates the */
1704 /* convention and attempts to change page state */
1705 /* without first setting busy we may not see it */
1706 /* because the page may already be busy. However */
1707 /* if such violations occur we will assert sooner */
1709 assert(dst_page
->busy
|| (ops
& UPL_POP_BUSY
));
1710 if (ops
& UPL_POP_DIRTY
) dst_page
->dirty
= TRUE
;
1711 if (ops
& UPL_POP_PAGEOUT
) dst_page
->pageout
= TRUE
;
1712 if (ops
& UPL_POP_PRECIOUS
) dst_page
->precious
= TRUE
;
1713 if (ops
& UPL_POP_ABSENT
) dst_page
->absent
= TRUE
;
1714 if (ops
& UPL_POP_BUSY
) dst_page
->busy
= TRUE
;
1717 if(ops
& UPL_POP_CLR
) {
1718 assert(dst_page
->busy
);
1719 if (ops
& UPL_POP_DIRTY
) dst_page
->dirty
= FALSE
;
1720 if (ops
& UPL_POP_PAGEOUT
) dst_page
->pageout
= FALSE
;
1721 if (ops
& UPL_POP_PRECIOUS
) dst_page
->precious
= FALSE
;
1722 if (ops
& UPL_POP_ABSENT
) dst_page
->absent
= FALSE
;
1723 if (ops
& UPL_POP_BUSY
) {
1724 dst_page
->busy
= FALSE
;
1725 PAGE_WAKEUP(dst_page
);
1731 vm_object_unlock(object
);
1732 return KERN_SUCCESS
;