177f14f2fSThomas Hellström /* SPDX-License-Identifier: MIT */ 277f14f2fSThomas Hellström /* 377f14f2fSThomas Hellström * Copyright © 2025 Intel Corporation 477f14f2fSThomas Hellström */ 577f14f2fSThomas Hellström 677f14f2fSThomas Hellström #ifndef _DRM_PAGEMAP_UTIL_H_ 777f14f2fSThomas Hellström #define _DRM_PAGEMAP_UTIL_H_ 877f14f2fSThomas Hellström 9*e44f47a9SThomas Hellström #include <linux/list.h> 10*e44f47a9SThomas Hellström #include <linux/mutex.h> 11*e44f47a9SThomas Hellström 1277f14f2fSThomas Hellström struct drm_device; 1377f14f2fSThomas Hellström struct drm_pagemap; 1477f14f2fSThomas Hellström struct drm_pagemap_cache; 15*e44f47a9SThomas Hellström struct drm_pagemap_owner; 1677f14f2fSThomas Hellström struct drm_pagemap_shrinker; 1777f14f2fSThomas Hellström 18*e44f47a9SThomas Hellström /** 19*e44f47a9SThomas Hellström * struct drm_pagemap_peer - Structure representing a fast interconnect peer 20*e44f47a9SThomas Hellström * @list: Pointer to a &struct drm_pagemap_owner_list used to keep track of peers 21*e44f47a9SThomas Hellström * @link: List link for @list's list of peers. 22*e44f47a9SThomas Hellström * @owner: Pointer to a &struct drm_pagemap_owner, common for a set of peers having 23*e44f47a9SThomas Hellström * fast interconnects. 24*e44f47a9SThomas Hellström * @private: Pointer private to the struct embedding this struct. 25*e44f47a9SThomas Hellström */ 26*e44f47a9SThomas Hellström struct drm_pagemap_peer { 27*e44f47a9SThomas Hellström struct drm_pagemap_owner_list *list; 28*e44f47a9SThomas Hellström struct list_head link; 29*e44f47a9SThomas Hellström struct drm_pagemap_owner *owner; 30*e44f47a9SThomas Hellström void *private; 31*e44f47a9SThomas Hellström }; 32*e44f47a9SThomas Hellström 33*e44f47a9SThomas Hellström /** 34*e44f47a9SThomas Hellström * struct drm_pagemap_owner_list - Keeping track of peers and owners 35*e44f47a9SThomas Hellström * @peer: List of peers. 36*e44f47a9SThomas Hellström * 37*e44f47a9SThomas Hellström * The owner list defines the scope where we identify peers having fast interconnects 38*e44f47a9SThomas Hellström * and a common owner. Typically a driver has a single global owner list to 39*e44f47a9SThomas Hellström * keep track of common owners for the driver's pagemaps. 40*e44f47a9SThomas Hellström */ 41*e44f47a9SThomas Hellström struct drm_pagemap_owner_list { 42*e44f47a9SThomas Hellström /** @lock: Mutex protecting the @peers list. */ 43*e44f47a9SThomas Hellström struct mutex lock; 44*e44f47a9SThomas Hellström /** @peers: List of peers. */ 45*e44f47a9SThomas Hellström struct list_head peers; 46*e44f47a9SThomas Hellström }; 47*e44f47a9SThomas Hellström 48*e44f47a9SThomas Hellström /* 49*e44f47a9SThomas Hellström * Convenience macro to define an owner list. 50*e44f47a9SThomas Hellström * Typically the owner list statically declared 51*e44f47a9SThomas Hellström * driver-wide. 52*e44f47a9SThomas Hellström */ 53*e44f47a9SThomas Hellström #define DRM_PAGEMAP_OWNER_LIST_DEFINE(_name) \ 54*e44f47a9SThomas Hellström struct drm_pagemap_owner_list _name = { \ 55*e44f47a9SThomas Hellström .lock = __MUTEX_INITIALIZER((_name).lock), \ 56*e44f47a9SThomas Hellström .peers = LIST_HEAD_INIT((_name).peers) } 57*e44f47a9SThomas Hellström 5877f14f2fSThomas Hellström void drm_pagemap_shrinker_add(struct drm_pagemap *dpagemap); 5977f14f2fSThomas Hellström 6077f14f2fSThomas Hellström int drm_pagemap_cache_lock_lookup(struct drm_pagemap_cache *cache); 6177f14f2fSThomas Hellström 6277f14f2fSThomas Hellström void drm_pagemap_cache_unlock_lookup(struct drm_pagemap_cache *cache); 6377f14f2fSThomas Hellström 6477f14f2fSThomas Hellström struct drm_pagemap_shrinker *drm_pagemap_shrinker_create_devm(struct drm_device *drm); 6577f14f2fSThomas Hellström 6677f14f2fSThomas Hellström struct drm_pagemap_cache *drm_pagemap_cache_create_devm(struct drm_pagemap_shrinker *shrinker); 6777f14f2fSThomas Hellström 6877f14f2fSThomas Hellström struct drm_pagemap *drm_pagemap_get_from_cache(struct drm_pagemap_cache *cache); 6977f14f2fSThomas Hellström 7077f14f2fSThomas Hellström void drm_pagemap_cache_set_pagemap(struct drm_pagemap_cache *cache, struct drm_pagemap *dpagemap); 7177f14f2fSThomas Hellström 7277f14f2fSThomas Hellström struct drm_pagemap *drm_pagemap_get_from_cache_if_active(struct drm_pagemap_cache *cache); 7377f14f2fSThomas Hellström 7477f14f2fSThomas Hellström #ifdef CONFIG_PROVE_LOCKING 7577f14f2fSThomas Hellström 7677f14f2fSThomas Hellström void drm_pagemap_shrinker_might_lock(struct drm_pagemap *dpagemap); 7777f14f2fSThomas Hellström 7877f14f2fSThomas Hellström #else 7977f14f2fSThomas Hellström 8077f14f2fSThomas Hellström static inline void drm_pagemap_shrinker_might_lock(struct drm_pagemap *dpagemap) 8177f14f2fSThomas Hellström { 8277f14f2fSThomas Hellström } 8377f14f2fSThomas Hellström 8477f14f2fSThomas Hellström #endif /* CONFIG_PROVE_LOCKING */ 8577f14f2fSThomas Hellström 86*e44f47a9SThomas Hellström void drm_pagemap_release_owner(struct drm_pagemap_peer *peer); 87*e44f47a9SThomas Hellström 88*e44f47a9SThomas Hellström int drm_pagemap_acquire_owner(struct drm_pagemap_peer *peer, 89*e44f47a9SThomas Hellström struct drm_pagemap_owner_list *owner_list, 90*e44f47a9SThomas Hellström bool (*has_interconnect)(struct drm_pagemap_peer *peer1, 91*e44f47a9SThomas Hellström struct drm_pagemap_peer *peer2)); 9277f14f2fSThomas Hellström #endif 93