Add a host_zeroes_pages flag to page_reporting_dev_info, allowing
drivers to declare that their host zeros reported pages on reclaim.
A static key gates the fast path.

Set PG_zeroed alongside PageReported in page_reporting_drain() when
host_zeroes_pages is enabled, so reported pages are marked as
known-zero at reporting time.

Signed-off-by: Michael S. Tsirkin <[email protected]>
Assisted-by: Claude:claude-opus-4-6
Assisted-by: cursor-agent:GPT-5.4-xhigh
---
 include/linux/page_reporting.h |  3 +++
 mm/page_reporting.c            | 13 ++++++++++++-
 mm/page_reporting.h            | 11 +++++++++++
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/include/linux/page_reporting.h b/include/linux/page_reporting.h
index fe648dfa3a7c..10faadfeb4fb 100644
--- a/include/linux/page_reporting.h
+++ b/include/linux/page_reporting.h
@@ -13,6 +13,9 @@ struct page_reporting_dev_info {
        int (*report)(struct page_reporting_dev_info *prdev,
                      struct scatterlist *sg, unsigned int nents);
 
+       /* If true, host zeros reported pages on reclaim */
+       bool host_zeroes_pages;
+
        /* work struct for processing reports */
        struct delayed_work work;
 
diff --git a/mm/page_reporting.c b/mm/page_reporting.c
index f0042d5743af..5e1e1a924b0c 100644
--- a/mm/page_reporting.c
+++ b/mm/page_reporting.c
@@ -50,6 +50,8 @@ EXPORT_SYMBOL_GPL(page_reporting_order);
 #define PAGE_REPORTING_DELAY   (2 * HZ)
 static struct page_reporting_dev_info __rcu *pr_dev_info __read_mostly;
 
+DEFINE_STATIC_KEY_FALSE(page_reporting_host_zeroes);
+
 enum {
        PAGE_REPORTING_IDLE = 0,
        PAGE_REPORTING_REQUESTED,
@@ -129,8 +131,11 @@ page_reporting_drain(struct page_reporting_dev_info *prdev,
                 * report on the new larger page when we make our way
                 * up to that higher order.
                 */
-               if (PageBuddy(page) && buddy_order(page) == order)
+               if (PageBuddy(page) && buddy_order(page) == order) {
                        __SetPageReported(page);
+                       if (page_reporting_host_zeroes_pages())
+                               __SetPageZeroed(page);
+               }
        } while ((sg = sg_next(sg)));
 
        /* reinitialize scatterlist now that it is empty */
@@ -386,6 +391,9 @@ int page_reporting_register(struct page_reporting_dev_info 
*prdev)
        /* Assign device to allow notifications */
        rcu_assign_pointer(pr_dev_info, prdev);
 
+       if (prdev->host_zeroes_pages)
+               static_branch_enable(&page_reporting_host_zeroes);
+
        /* enable page reporting notification */
        if (!static_key_enabled(&page_reporting_enabled)) {
                static_branch_enable(&page_reporting_enabled);
@@ -410,6 +418,9 @@ void page_reporting_unregister(struct 
page_reporting_dev_info *prdev)
 
                /* Flush any existing work, and lock it out */
                cancel_delayed_work_sync(&prdev->work);
+
+               if (prdev->host_zeroes_pages)
+                       static_branch_disable(&page_reporting_host_zeroes);
        }
 
        mutex_unlock(&page_reporting_mutex);
diff --git a/mm/page_reporting.h b/mm/page_reporting.h
index c51dbc228b94..a53ab22f4c49 100644
--- a/mm/page_reporting.h
+++ b/mm/page_reporting.h
@@ -12,9 +12,15 @@
 
 #ifdef CONFIG_PAGE_REPORTING
 DECLARE_STATIC_KEY_FALSE(page_reporting_enabled);
+DECLARE_STATIC_KEY_FALSE(page_reporting_host_zeroes);
 extern unsigned int page_reporting_order;
 void __page_reporting_notify(void);
 
+static inline bool page_reporting_host_zeroes_pages(void)
+{
+       return static_branch_unlikely(&page_reporting_host_zeroes);
+}
+
 static inline bool page_reported(struct page *page)
 {
        return static_branch_unlikely(&page_reporting_enabled) &&
@@ -46,6 +52,11 @@ static inline void page_reporting_notify_free(unsigned int 
order)
 #else /* CONFIG_PAGE_REPORTING */
 #define page_reported(_page)   false
 
+static inline bool page_reporting_host_zeroes_pages(void)
+{
+       return false;
+}
+
 static inline void page_reporting_notify_free(unsigned int order)
 {
 }
-- 
MST


Reply via email to