xref: /linux/include/drm/drm_pagemap_util.h (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
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