This looks fine except for a few nitpicks below: > } > > + dev_pagemap_enable_ops(); > pgmap->type = MEMORY_DEVICE_FS_DAX; > pgmap->page_free = generic_dax_pagefree; > pgmap->data = owner; > @@ -215,6 +216,7 @@ void fs_dax_release(struct dax_device *dax_dev, void *owner) > pgmap->type = MEMORY_DEVICE_HOST; > pgmap->page_free = NULL; > pgmap->data = NULL; > + dev_pagemap_disable_ops(); should these be get/put instead of enable/disable given that they implement a refcount? > +#ifdef CONFIG_DEV_PAGEMAP_OPS > +void __put_devmap_managed_page(struct page *page); > +DECLARE_STATIC_KEY_FALSE(devmap_managed_key); > +static inline bool put_devmap_managed_page(struct page *page) > { > + if (!static_branch_unlikely(&devmap_managed_key)) > + return false; > + if (!is_zone_device_page(page)) > + return false; > + switch (page->pgmap->type) { > + case MEMORY_DEVICE_PRIVATE: > + case MEMORY_DEVICE_PUBLIC: > + case MEMORY_DEVICE_FS_DAX: > + __put_devmap_managed_page(page); > + return true; > + default: > + break; > + } > + return false; Should the switch be moved into the out of line version to keep the inline instructions at a minimum? > + * pages go idle. > + */ > +void dev_pagemap_enable_ops(void) > +{ > + if (atomic_inc_return(&devmap_enable) == 1) > + static_branch_enable(&devmap_managed_key); > +} > +EXPORT_SYMBOL(dev_pagemap_enable_ops); _GPL? > +EXPORT_SYMBOL(dev_pagemap_disable_ops); Same.