Add a write-only module parameter 'flush' that triggers immediate
page reporting.  The value specifies a page budget: at least
this many pages (at page_reporting_order) will be reported,
or all unreported pages if fewer remain.  The actual number
reported may exceed the budget since each reporting pass
processes a full cycle across all zones.

This is helpful when there is a lot of memory freed quickly,
and a single cycle may not process all free pages due to
internal budget limits.

  echo 512 > /sys/module/page_reporting/parameters/flush

Signed-off-by: Michael S. Tsirkin <[email protected]>
Assisted-by: Claude:claude-opus-4-6
Assisted-by: cursor-agent:GPT-5.4-xhigh
---
 mm/page_reporting.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/mm/page_reporting.c b/mm/page_reporting.c
index 6c957a9daeef..f4a0e27ac7fb 100644
--- a/mm/page_reporting.c
+++ b/mm/page_reporting.c
@@ -358,6 +358,48 @@ static void page_reporting_process(struct work_struct 
*work)
 static DEFINE_MUTEX(page_reporting_mutex);
 DEFINE_STATIC_KEY_FALSE(page_reporting_enabled);
 
+static int page_reporting_flush_set(const char *val,
+                                   const struct kernel_param *kp)
+{
+       struct page_reporting_dev_info *prdev;
+       unsigned int budget;
+       int err;
+
+       err = kstrtouint(val, 0, &budget);
+       if (err)
+               return err;
+       if (!budget)
+               return 0;
+
+       mutex_lock(&page_reporting_mutex);
+       prdev = rcu_dereference_protected(pr_dev_info,
+                               lockdep_is_held(&page_reporting_mutex));
+       if (prdev) {
+               unsigned int reported;
+
+               for (reported = 0; reported < budget;
+                    reported += prdev->capacity) {
+                       flush_delayed_work(&prdev->work);
+                       __page_reporting_request(prdev);
+                       flush_delayed_work(&prdev->work);
+                       if (atomic_read(&prdev->state) == PAGE_REPORTING_IDLE)
+                               break;
+                       if (signal_pending(current))
+                               break;
+               }
+       }
+       mutex_unlock(&page_reporting_mutex);
+       return 0;
+}
+
+static const struct kernel_param_ops flush_ops = {
+       .set = page_reporting_flush_set,
+       .get = param_get_uint,
+};
+static unsigned int page_reporting_flush;
+module_param_cb(flush, &flush_ops, &page_reporting_flush, 0200);
+MODULE_PARM_DESC(flush, "Report at least N pages at page_reporting_order, or 
until all reported");
+
 int page_reporting_register(struct page_reporting_dev_info *prdev)
 {
        int err = 0;
-- 
MST


Reply via email to