/* SPDX-License-Identifier: MIT */ /* * Copyright © 2025 Intel Corporation */ #ifndef _DRM_PAGEMAP_UTIL_H_ #define _DRM_PAGEMAP_UTIL_H_ #include #include struct drm_device; struct drm_pagemap; struct drm_pagemap_cache; struct drm_pagemap_owner; struct drm_pagemap_shrinker; /** * struct drm_pagemap_peer - Structure representing a fast interconnect peer * @list: Pointer to a &struct drm_pagemap_owner_list used to keep track of peers * @link: List link for @list's list of peers. * @owner: Pointer to a &struct drm_pagemap_owner, common for a set of peers having * fast interconnects. * @private: Pointer private to the struct embedding this struct. */ struct drm_pagemap_peer { struct drm_pagemap_owner_list *list; struct list_head link; struct drm_pagemap_owner *owner; void *private; }; /** * struct drm_pagemap_owner_list - Keeping track of peers and owners * @peer: List of peers. * * The owner list defines the scope where we identify peers having fast interconnects * and a common owner. Typically a driver has a single global owner list to * keep track of common owners for the driver's pagemaps. */ struct drm_pagemap_owner_list { /** @lock: Mutex protecting the @peers list. */ struct mutex lock; /** @peers: List of peers. */ struct list_head peers; }; /* * Convenience macro to define an owner list. * Typically the owner list statically declared * driver-wide. */ #define DRM_PAGEMAP_OWNER_LIST_DEFINE(_name) \ struct drm_pagemap_owner_list _name = { \ .lock = __MUTEX_INITIALIZER((_name).lock), \ .peers = LIST_HEAD_INIT((_name).peers) } void drm_pagemap_shrinker_add(struct drm_pagemap *dpagemap); int drm_pagemap_cache_lock_lookup(struct drm_pagemap_cache *cache); void drm_pagemap_cache_unlock_lookup(struct drm_pagemap_cache *cache); struct drm_pagemap_shrinker *drm_pagemap_shrinker_create_devm(struct drm_device *drm); struct drm_pagemap_cache *drm_pagemap_cache_create_devm(struct drm_pagemap_shrinker *shrinker); struct drm_pagemap *drm_pagemap_get_from_cache(struct drm_pagemap_cache *cache); void drm_pagemap_cache_set_pagemap(struct drm_pagemap_cache *cache, struct drm_pagemap *dpagemap); struct drm_pagemap *drm_pagemap_get_from_cache_if_active(struct drm_pagemap_cache *cache); #ifdef CONFIG_PROVE_LOCKING void drm_pagemap_shrinker_might_lock(struct drm_pagemap *dpagemap); #else static inline void drm_pagemap_shrinker_might_lock(struct drm_pagemap *dpagemap) { } #endif /* CONFIG_PROVE_LOCKING */ void drm_pagemap_release_owner(struct drm_pagemap_peer *peer); int drm_pagemap_acquire_owner(struct drm_pagemap_peer *peer, struct drm_pagemap_owner_list *owner_list, bool (*has_interconnect)(struct drm_pagemap_peer *peer1, struct drm_pagemap_peer *peer2)); #endif