mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
drm/pagemap: Add helper to access zone_device_data
This new helper helps ensure all accesses to zone_device_data use the correct API whether the page is part of a folio or not. v2: - Move to drm_pagemap.h, stick to folio_zone_device_data (Matthew Brost) - Return struct drm_pagemap_zdd * (Matthew Brost) v3: - Add stub for !CONFIG_ZONE_DEVICE (CI) Cc: Andrew Morton <akpm@linux-foundation.org> Cc: David Hildenbrand <david@kernel.org> Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Cc: Liam R. Howlett <Liam.Howlett@oracle.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Mike Rapoport <rppt@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Michal Hocko <mhocko@suse.com> Cc: Zi Yan <ziy@nvidia.com> Cc: Alistair Popple <apopple@nvidia.com> Cc: Balbir Singh <balbirs@nvidia.com> Cc: linux-mm@kvack.org Suggested-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Francois Dugast <francois.dugast@intel.com> Signed-off-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260312192126.2024853-3-francois.dugast@intel.com
This commit is contained in:
parent
440ec190c2
commit
2e03c0c5c5
|
|
@ -1488,12 +1488,15 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
|
||||||
order = drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages);
|
order = drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages);
|
||||||
if (is_device_private_page(page) ||
|
if (is_device_private_page(page) ||
|
||||||
is_device_coherent_page(page)) {
|
is_device_coherent_page(page)) {
|
||||||
|
struct drm_pagemap_zdd *__zdd =
|
||||||
|
drm_pagemap_page_zone_device_data(page);
|
||||||
|
|
||||||
if (!ctx->allow_mixed &&
|
if (!ctx->allow_mixed &&
|
||||||
zdd != page->zone_device_data && i > 0) {
|
zdd != __zdd && i > 0) {
|
||||||
err = -EOPNOTSUPP;
|
err = -EOPNOTSUPP;
|
||||||
goto err_unmap;
|
goto err_unmap;
|
||||||
}
|
}
|
||||||
zdd = page->zone_device_data;
|
zdd = __zdd;
|
||||||
if (pagemap != page_pgmap(page)) {
|
if (pagemap != page_pgmap(page)) {
|
||||||
if (pagemap) {
|
if (pagemap) {
|
||||||
err = -EOPNOTSUPP;
|
err = -EOPNOTSUPP;
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@ static int drm_pagemap_migrate_map_pages(struct device *dev,
|
||||||
order = folio_order(folio);
|
order = folio_order(folio);
|
||||||
|
|
||||||
if (is_device_private_page(page)) {
|
if (is_device_private_page(page)) {
|
||||||
struct drm_pagemap_zdd *zdd = page->zone_device_data;
|
struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
|
||||||
struct drm_pagemap *dpagemap = zdd->dpagemap;
|
struct drm_pagemap *dpagemap = zdd->dpagemap;
|
||||||
struct drm_pagemap_addr addr;
|
struct drm_pagemap_addr addr;
|
||||||
|
|
||||||
|
|
@ -323,7 +323,7 @@ static void drm_pagemap_migrate_unmap_pages(struct device *dev,
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (is_zone_device_page(page)) {
|
if (is_zone_device_page(page)) {
|
||||||
struct drm_pagemap_zdd *zdd = page->zone_device_data;
|
struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
|
||||||
struct drm_pagemap *dpagemap = zdd->dpagemap;
|
struct drm_pagemap *dpagemap = zdd->dpagemap;
|
||||||
|
|
||||||
dpagemap->ops->device_unmap(dpagemap, dev, &pagemap_addr[i]);
|
dpagemap->ops->device_unmap(dpagemap, dev, &pagemap_addr[i]);
|
||||||
|
|
@ -601,7 +601,8 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation,
|
||||||
|
|
||||||
pages[i] = NULL;
|
pages[i] = NULL;
|
||||||
if (src_page && is_device_private_page(src_page)) {
|
if (src_page && is_device_private_page(src_page)) {
|
||||||
struct drm_pagemap_zdd *src_zdd = src_page->zone_device_data;
|
struct drm_pagemap_zdd *src_zdd =
|
||||||
|
drm_pagemap_page_zone_device_data(src_page);
|
||||||
|
|
||||||
if (page_pgmap(src_page) == pagemap &&
|
if (page_pgmap(src_page) == pagemap &&
|
||||||
!mdetails->can_migrate_same_pagemap) {
|
!mdetails->can_migrate_same_pagemap) {
|
||||||
|
|
@ -723,8 +724,8 @@ static int drm_pagemap_migrate_populate_ram_pfn(struct vm_area_struct *vas,
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (fault_page) {
|
if (fault_page) {
|
||||||
if (src_page->zone_device_data !=
|
if (drm_pagemap_page_zone_device_data(src_page) !=
|
||||||
fault_page->zone_device_data)
|
drm_pagemap_page_zone_device_data(fault_page))
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1065,7 +1066,7 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
|
||||||
void *buf;
|
void *buf;
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
|
|
||||||
zdd = page->zone_device_data;
|
zdd = drm_pagemap_page_zone_device_data(page);
|
||||||
if (time_before64(get_jiffies_64(), zdd->devmem_allocation->timeslice_expiration))
|
if (time_before64(get_jiffies_64(), zdd->devmem_allocation->timeslice_expiration))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -1148,7 +1149,9 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
|
||||||
*/
|
*/
|
||||||
static void drm_pagemap_folio_free(struct folio *folio)
|
static void drm_pagemap_folio_free(struct folio *folio)
|
||||||
{
|
{
|
||||||
drm_pagemap_zdd_put(folio->page.zone_device_data);
|
struct page *page = folio_page(folio, 0);
|
||||||
|
|
||||||
|
drm_pagemap_zdd_put(drm_pagemap_page_zone_device_data(page));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1164,7 +1167,7 @@ static void drm_pagemap_folio_free(struct folio *folio)
|
||||||
*/
|
*/
|
||||||
static vm_fault_t drm_pagemap_migrate_to_ram(struct vm_fault *vmf)
|
static vm_fault_t drm_pagemap_migrate_to_ram(struct vm_fault *vmf)
|
||||||
{
|
{
|
||||||
struct drm_pagemap_zdd *zdd = vmf->page->zone_device_data;
|
struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(vmf->page);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = __drm_pagemap_migrate_to_ram(vmf->vma,
|
err = __drm_pagemap_migrate_to_ram(vmf->vma,
|
||||||
|
|
@ -1230,7 +1233,7 @@ EXPORT_SYMBOL_GPL(drm_pagemap_devmem_init);
|
||||||
*/
|
*/
|
||||||
struct drm_pagemap *drm_pagemap_page_to_dpagemap(struct page *page)
|
struct drm_pagemap *drm_pagemap_page_to_dpagemap(struct page *page)
|
||||||
{
|
{
|
||||||
struct drm_pagemap_zdd *zdd = page->zone_device_data;
|
struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
|
||||||
|
|
||||||
return zdd->devmem_allocation->dpagemap;
|
return zdd->devmem_allocation->dpagemap;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <linux/dma-direction.h>
|
#include <linux/dma-direction.h>
|
||||||
#include <linux/hmm.h>
|
#include <linux/hmm.h>
|
||||||
|
#include <linux/memremap.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
#define NR_PAGES(order) (1U << (order))
|
#define NR_PAGES(order) (1U << (order))
|
||||||
|
|
@ -367,6 +368,26 @@ void drm_pagemap_destroy(struct drm_pagemap *dpagemap, bool is_atomic_or_reclaim
|
||||||
|
|
||||||
int drm_pagemap_reinit(struct drm_pagemap *dpagemap);
|
int drm_pagemap_reinit(struct drm_pagemap *dpagemap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* drm_pagemap_page_zone_device_data() - Page to zone_device_data
|
||||||
|
* @page: Pointer to the page
|
||||||
|
*
|
||||||
|
* Return: Page's zone_device_data
|
||||||
|
*/
|
||||||
|
static inline struct drm_pagemap_zdd *drm_pagemap_page_zone_device_data(struct page *page)
|
||||||
|
{
|
||||||
|
struct folio *folio = page_folio(page);
|
||||||
|
|
||||||
|
return folio_zone_device_data(folio);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline struct drm_pagemap_zdd *drm_pagemap_page_zone_device_data(struct page *page)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* IS_ENABLED(CONFIG_ZONE_DEVICE) */
|
#endif /* IS_ENABLED(CONFIG_ZONE_DEVICE) */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user