struct list_head *list = &area->free_list[mt];
unsigned int page_len = PAGE_SIZE << order;
struct page *page, *next;
+ long budget;
int err = 0;
/*
spin_lock_irq(&zone->lock);
+ /*
+ * Limit how many calls we will be making to the page reporting
+ * device for this list. By doing this we avoid processing any
+ * given list for too long.
+ *
+ * The current value used allows us enough calls to process over a
+ * sixteenth of the current list plus one additional call to handle
+ * any pages that may have already been present from the previous
+ * list processed. This should result in us reporting all pages on
+ * an idle system in about 30 seconds.
+ *
+ * The division here should be cheap since PAGE_REPORTING_CAPACITY
+ * should always be a power of 2.
+ */
+ budget = DIV_ROUND_UP(area->nr_free, PAGE_REPORTING_CAPACITY * 16);
+
/* loop through free list adding unreported pages to sg list */
list_for_each_entry_safe(page, next, list, lru) {
/* We are going to skip over the reported pages. */
if (PageReported(page))
continue;
+ /*
+ * If we fully consumed our budget then update our
+ * state to indicate that we are requesting additional
+ * processing and exit this list.
+ */
+ if (budget < 0) {
+ atomic_set(&prdev->state, PAGE_REPORTING_REQUESTED);
+ next = page;
+ break;
+ }
+
/* Attempt to pull page from list and place in scatterlist */
if (*offset) {
if (!__isolate_free_page(page, order)) {
}
/*
- * Make the first non-processed page in the free list
+ * Make the first non-reported page in the free list
* the new head of the free list before we release the
* zone lock.
*/
/* reset offset since the full list was reported */
*offset = PAGE_REPORTING_CAPACITY;
+ /* update budget to reflect call to report function */
+ budget--;
+
/* reacquire zone lock and resume processing */
spin_lock_irq(&zone->lock);