xref: /linux/include/drm/drm_pagemap_util.h (revision 69050f8d6d075dc01af7a5f2f550a8067510366f)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright © 2025 Intel Corporation
4  */
5 
6 #ifndef _DRM_PAGEMAP_UTIL_H_
7 #define _DRM_PAGEMAP_UTIL_H_
8 
9 #include <linux/list.h>
10 #include <linux/mutex.h>
11 
12 struct drm_device;
13 struct drm_pagemap;
14 struct drm_pagemap_cache;
15 struct drm_pagemap_owner;
16 struct drm_pagemap_shrinker;
17 
18 /**
19  * struct drm_pagemap_peer - Structure representing a fast interconnect peer
20  * @list: Pointer to a &struct drm_pagemap_owner_list used to keep track of peers
21  * @link: List link for @list's list of peers.
22  * @owner: Pointer to a &struct drm_pagemap_owner, common for a set of peers having
23  * fast interconnects.
24  * @private: Pointer private to the struct embedding this struct.
25  */
26 struct drm_pagemap_peer {
27 	struct drm_pagemap_owner_list *list;
28 	struct list_head link;
29 	struct drm_pagemap_owner *owner;
30 	void *private;
31 };
32 
33 /**
34  * struct drm_pagemap_owner_list - Keeping track of peers and owners
35  * @peer: List of peers.
36  *
37  * The owner list defines the scope where we identify peers having fast interconnects
38  * and a common owner. Typically a driver has a single global owner list to
39  * keep track of common owners for the driver's pagemaps.
40  */
41 struct drm_pagemap_owner_list {
42 	/** @lock: Mutex protecting the @peers list. */
43 	struct mutex lock;
44 	/** @peers: List of peers. */
45 	struct list_head peers;
46 };
47 
48 /*
49  * Convenience macro to define an owner list.
50  * Typically the owner list statically declared
51  * driver-wide.
52  */
53 #define DRM_PAGEMAP_OWNER_LIST_DEFINE(_name)	\
54 	struct drm_pagemap_owner_list _name = {	\
55 	  .lock = __MUTEX_INITIALIZER((_name).lock),	\
56 	  .peers = LIST_HEAD_INIT((_name).peers) }
57 
58 void drm_pagemap_shrinker_add(struct drm_pagemap *dpagemap);
59 
60 int drm_pagemap_cache_lock_lookup(struct drm_pagemap_cache *cache);
61 
62 void drm_pagemap_cache_unlock_lookup(struct drm_pagemap_cache *cache);
63 
64 struct drm_pagemap_shrinker *drm_pagemap_shrinker_create_devm(struct drm_device *drm);
65 
66 struct drm_pagemap_cache *drm_pagemap_cache_create_devm(struct drm_pagemap_shrinker *shrinker);
67 
68 struct drm_pagemap *drm_pagemap_get_from_cache(struct drm_pagemap_cache *cache);
69 
70 void drm_pagemap_cache_set_pagemap(struct drm_pagemap_cache *cache, struct drm_pagemap *dpagemap);
71 
72 struct drm_pagemap *drm_pagemap_get_from_cache_if_active(struct drm_pagemap_cache *cache);
73 
74 #ifdef CONFIG_PROVE_LOCKING
75 
76 void drm_pagemap_shrinker_might_lock(struct drm_pagemap *dpagemap);
77 
78 #else
79 
80 static inline void drm_pagemap_shrinker_might_lock(struct drm_pagemap *dpagemap)
81 {
82 }
83 
84 #endif /* CONFIG_PROVE_LOCKING */
85 
86 void drm_pagemap_release_owner(struct drm_pagemap_peer *peer);
87 
88 int drm_pagemap_acquire_owner(struct drm_pagemap_peer *peer,
89 			      struct drm_pagemap_owner_list *owner_list,
90 			      bool (*has_interconnect)(struct drm_pagemap_peer *peer1,
91 						       struct drm_pagemap_peer *peer2));
92 #endif
93