* Scan the active queue. If there is no shortage of inactive pages, scan a * small portion of the queue in order to maintain quasi-LRU. */
| 1169 | * small portion of the queue in order to maintain quasi-LRU. |
| 1170 | */ |
| 1171 | static void |
| 1172 | vm_pageout_scan_active(struct vm_domain *vmd, int page_shortage) |
| 1173 | { |
| 1174 | struct scan_state ss; |
| 1175 | vm_object_t object; |
| 1176 | vm_page_t m, marker; |
| 1177 | struct vm_pagequeue *pq; |
| 1178 | vm_page_astate_t old, new; |
| 1179 | long min_scan; |
| 1180 | int act_delta, max_scan, ps_delta, refs, scan_tick; |
| 1181 | uint8_t nqueue; |
| 1182 | |
| 1183 | marker = &vmd->vmd_markers[PQ_ACTIVE]; |
| 1184 | pq = &vmd->vmd_pagequeues[PQ_ACTIVE]; |
| 1185 | vm_pagequeue_lock(pq); |
| 1186 | |
| 1187 | /* |
| 1188 | * If we're just idle polling attempt to visit every |
| 1189 | * active page within 'update_period' seconds. |
| 1190 | */ |
| 1191 | scan_tick = ticks; |
| 1192 | if (vm_pageout_update_period != 0) { |
| 1193 | min_scan = pq->pq_cnt; |
| 1194 | min_scan *= scan_tick - vmd->vmd_last_active_scan; |
| 1195 | min_scan /= hz * vm_pageout_update_period; |
| 1196 | } else |
| 1197 | min_scan = 0; |
| 1198 | if (min_scan > 0 || (page_shortage > 0 && pq->pq_cnt > 0)) |
| 1199 | vmd->vmd_last_active_scan = scan_tick; |
| 1200 | |
| 1201 | /* |
| 1202 | * Scan the active queue for pages that can be deactivated. Update |
| 1203 | * the per-page activity counter and use it to identify deactivation |
| 1204 | * candidates. Held pages may be deactivated. |
| 1205 | * |
| 1206 | * To avoid requeuing each page that remains in the active queue, we |
| 1207 | * implement the CLOCK algorithm. To keep the implementation of the |
| 1208 | * enqueue operation consistent for all page queues, we use two hands, |
| 1209 | * represented by marker pages. Scans begin at the first hand, which |
| 1210 | * precedes the second hand in the queue. When the two hands meet, |
| 1211 | * they are moved back to the head and tail of the queue, respectively, |
| 1212 | * and scanning resumes. |
| 1213 | */ |
| 1214 | max_scan = page_shortage > 0 ? pq->pq_cnt : min_scan; |
| 1215 | act_scan: |
| 1216 | vm_pageout_init_scan(&ss, pq, marker, &vmd->vmd_clock[0], max_scan); |
| 1217 | while ((m = vm_pageout_next(&ss, false)) != NULL) { |
| 1218 | if (__predict_false(m == &vmd->vmd_clock[1])) { |
| 1219 | vm_pagequeue_lock(pq); |
| 1220 | TAILQ_REMOVE(&pq->pq_pl, &vmd->vmd_clock[0], plinks.q); |
| 1221 | TAILQ_REMOVE(&pq->pq_pl, &vmd->vmd_clock[1], plinks.q); |
| 1222 | TAILQ_INSERT_HEAD(&pq->pq_pl, &vmd->vmd_clock[0], |
| 1223 | plinks.q); |
| 1224 | TAILQ_INSERT_TAIL(&pq->pq_pl, &vmd->vmd_clock[1], |
| 1225 | plinks.q); |
| 1226 | max_scan -= ss.scanned; |
| 1227 | vm_pageout_end_scan(&ss); |
| 1228 | goto act_scan; |
no test coverage detected