* Attempt to launder the specified number of pages. * * Returns the number of pages successfully laundered. */
| 719 | * Returns the number of pages successfully laundered. |
| 720 | */ |
| 721 | static int |
| 722 | vm_pageout_launder(struct vm_domain *vmd, int launder, bool in_shortfall) |
| 723 | { |
| 724 | struct scan_state ss; |
| 725 | struct vm_pagequeue *pq; |
| 726 | vm_object_t object; |
| 727 | vm_page_t m, marker; |
| 728 | vm_page_astate_t new, old; |
| 729 | int act_delta, error, numpagedout, queue, refs, starting_target; |
| 730 | int vnodes_skipped; |
| 731 | bool pageout_ok; |
| 732 | |
| 733 | object = NULL; |
| 734 | starting_target = launder; |
| 735 | vnodes_skipped = 0; |
| 736 | |
| 737 | /* |
| 738 | * Scan the laundry queues for pages eligible to be laundered. We stop |
| 739 | * once the target number of dirty pages have been laundered, or once |
| 740 | * we've reached the end of the queue. A single iteration of this loop |
| 741 | * may cause more than one page to be laundered because of clustering. |
| 742 | * |
| 743 | * As an optimization, we avoid laundering from PQ_UNSWAPPABLE when no |
| 744 | * swap devices are configured. |
| 745 | */ |
| 746 | if (atomic_load_acq_int(&swapdev_enabled)) |
| 747 | queue = PQ_UNSWAPPABLE; |
| 748 | else |
| 749 | queue = PQ_LAUNDRY; |
| 750 | |
| 751 | scan: |
| 752 | marker = &vmd->vmd_markers[queue]; |
| 753 | pq = &vmd->vmd_pagequeues[queue]; |
| 754 | vm_pagequeue_lock(pq); |
| 755 | vm_pageout_init_scan(&ss, pq, marker, NULL, pq->pq_cnt); |
| 756 | while (launder > 0 && (m = vm_pageout_next(&ss, false)) != NULL) { |
| 757 | if (__predict_false((m->flags & PG_MARKER) != 0)) |
| 758 | continue; |
| 759 | |
| 760 | /* |
| 761 | * Don't touch a page that was removed from the queue after the |
| 762 | * page queue lock was released. Otherwise, ensure that any |
| 763 | * pending queue operations, such as dequeues for wired pages, |
| 764 | * are handled. |
| 765 | */ |
| 766 | if (vm_pageout_defer(m, queue, true)) |
| 767 | continue; |
| 768 | |
| 769 | /* |
| 770 | * Lock the page's object. |
| 771 | */ |
| 772 | if (object == NULL || object != m->object) { |
| 773 | if (object != NULL) |
| 774 | VM_OBJECT_WUNLOCK(object); |
| 775 | object = atomic_load_ptr(&m->object); |
| 776 | if (__predict_false(object == NULL)) |
| 777 | /* The page is being freed by another thread. */ |
| 778 | continue; |
no test coverage detected