diff options
Diffstat (limited to 'include/drm/drm_file.h')
-rw-r--r-- | include/drm/drm_file.h | 152 |
1 files changed, 127 insertions, 25 deletions
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 716990bace10..5c3b2aa3e69d 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -41,21 +41,28 @@ struct dma_fence; struct drm_file; struct drm_device; +struct drm_printer; struct device; struct file; +extern struct xarray drm_minors_xa; + /* * FIXME: Not sure we want to have drm_minor here in the end, but to avoid * header include loops we need it here for now. */ -/* Note that the order of this enum is ABI (it determines +/* Note that the values of this enum are ABI (it determines * /dev/dri/renderD* numbers). + * + * Setting DRM_MINOR_ACCEL to 32 gives enough space for more drm minors to + * be implemented before we hit any future */ enum drm_minor_type { - DRM_MINOR_PRIMARY, - DRM_MINOR_CONTROL, - DRM_MINOR_RENDER, + DRM_MINOR_PRIMARY = 0, + DRM_MINOR_CONTROL = 1, + DRM_MINOR_RENDER = 2, + DRM_MINOR_ACCEL = 32, }; /** @@ -70,14 +77,12 @@ enum drm_minor_type { struct drm_minor { /* private: */ int index; /* Minor device number */ - int type; /* Control or render */ + int type; /* Control or render or accel */ struct device *kdev; /* Linux device */ struct drm_device *dev; + struct dentry *debugfs_symlink; struct dentry *debugfs_root; - - struct list_head debugfs_list; - struct mutex debugfs_lock; /* Protects debugfs_list. */ }; /** @@ -224,19 +229,57 @@ struct drm_file { bool is_master; /** + * @supports_virtualized_cursor_plane: + * + * This client is capable of handling the cursor plane with the + * restrictions imposed on it by the virtualized drivers. + * + * This implies that the cursor plane has to behave like a cursor + * i.e. track cursor movement. It also requires setting of the + * hotspot properties by the client on the cursor plane. + */ + bool supports_virtualized_cursor_plane; + + /** * @master: * - * Master this node is currently associated with. Only relevant if - * drm_is_primary_client() returns true. Note that this only - * matches &drm_device.master if the master is the currently active one. + * Master this node is currently associated with. Protected by struct + * &drm_device.master_mutex, and serialized by @master_lookup_lock. + * + * Only relevant if drm_is_primary_client() returns true. Note that + * this only matches &drm_device.master if the master is the currently + * active one. + * + * To update @master, both &drm_device.master_mutex and + * @master_lookup_lock need to be held, therefore holding either of + * them is safe and enough for the read side. + * + * When dereferencing this pointer, either hold struct + * &drm_device.master_mutex for the duration of the pointer's use, or + * use drm_file_get_master() if struct &drm_device.master_mutex is not + * currently held and there is no other need to hold it. This prevents + * @master from being freed during use. * * See also @authentication and @is_master and the :ref:`section on * primary nodes and authentication <drm_primary_node>`. */ struct drm_master *master; - /** @pid: Process that opened this file. */ - struct pid *pid; + /** @master_lookup_lock: Serializes @master. */ + spinlock_t master_lookup_lock; + + /** + * @pid: Process that is using this file. + * + * Must only be dereferenced under a rcu_read_lock or equivalent. + * + * Updates are guarded with dev->filelist_mutex and reference must be + * dropped after a RCU grace period to accommodate lockless readers. + */ + struct pid __rcu *pid; + + /** @client_id: A unique id for fdinfo */ + u64 client_id; /** @magic: Authentication magic, see @authenticated. */ drm_magic_t magic; @@ -346,10 +389,17 @@ struct drm_file { */ struct drm_prime_file_private prime; - /* private: */ -#if IS_ENABLED(CONFIG_DRM_LEGACY) - unsigned long lock_count; /* DRI1 legacy lock count */ -#endif + /** + * @client_name: + * + * Userspace-provided name; useful for accounting and debugging. + */ + const char *client_name; + + /** + * @client_name_lock: Protects @client_name. + */ + struct mutex client_name_lock; }; /** @@ -381,7 +431,31 @@ static inline bool drm_is_render_client(const struct drm_file *file_priv) return file_priv->minor->type == DRM_MINOR_RENDER; } +/** + * drm_is_accel_client - is this an open file of the compute acceleration node + * @file_priv: DRM file + * + * Returns true if this is an open file of the compute acceleration node, i.e. + * &drm_file.minor of @file_priv is a accel minor. + * + * See also :doc:`Introduction to compute accelerators subsystem + * </accel/introduction>`. + */ +static inline bool drm_is_accel_client(const struct drm_file *file_priv) +{ + return file_priv->minor->type == DRM_MINOR_ACCEL; +} + +__printf(2, 3) +void drm_file_err(struct drm_file *file_priv, const char *fmt, ...); + +void drm_file_update_pid(struct drm_file *); + +struct drm_minor *drm_minor_acquire(struct xarray *minors_xa, unsigned int minor_id); +void drm_minor_release(struct drm_minor *minor); + int drm_open(struct inode *inode, struct file *filp); +int drm_open_helper(struct file *filp, struct drm_minor *minor); ssize_t drm_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset); int drm_release(struct inode *inode, struct file *filp); @@ -399,16 +473,44 @@ void drm_event_cancel_free(struct drm_device *dev, struct drm_pending_event *p); void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e); void drm_send_event(struct drm_device *dev, struct drm_pending_event *e); +void drm_send_event_timestamp_locked(struct drm_device *dev, + struct drm_pending_event *e, + ktime_t timestamp); -struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags); +/** + * struct drm_memory_stats - GEM object stats associated + * @shared: Total size of GEM objects shared between processes + * @private: Total size of GEM objects + * @resident: Total size of GEM objects backing pages + * @purgeable: Total size of GEM objects that can be purged (resident and not active) + * @active: Total size of GEM objects active on one or more engines + * + * Used by drm_print_memory_stats() + */ +struct drm_memory_stats { + u64 shared; + u64 private; + u64 resident; + u64 purgeable; + u64 active; +}; + +enum drm_gem_object_status; -#ifdef CONFIG_MMU -struct drm_vma_offset_manager; -unsigned long drm_get_unmapped_area(struct file *file, - unsigned long uaddr, unsigned long len, - unsigned long pgoff, unsigned long flags, - struct drm_vma_offset_manager *mgr); -#endif /* CONFIG_MMU */ +int drm_memory_stats_is_zero(const struct drm_memory_stats *stats); +void drm_fdinfo_print_size(struct drm_printer *p, + const char *prefix, + const char *stat, + const char *region, + u64 sz); +void drm_print_memory_stats(struct drm_printer *p, + const struct drm_memory_stats *stats, + enum drm_gem_object_status supported_status, + const char *region); +void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file); +void drm_show_fdinfo(struct seq_file *m, struct file *f); + +struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags); #endif /* _DRM_FILE_H_ */ |