drm/vc4: Expose performance counters to userspace
The V3D engine has various hardware counters which might be interesting to userspace performance analysis tools. Expose new ioctls to create/destroy a performance monitor object and query the counter values of this perfmance monitor. Note that a perfomance monitor is given an ID that is only valid on the file descriptor it has been allocated from. A performance monitor can be attached to a CL submission and the driver will enable HW counters for this request and update the performance monitor values at the end of the job. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Reviewed-by: Eric Anholt <eric@anholt.net> Signed-off-by: Eric Anholt <eric@anholt.net> Link: https://patchwork.freedesktop.org/patch/msgid/20180112090926.12538-1-boris.brezillon@free-electrons.com
This commit is contained in:

committed by
Eric Anholt

parent
9c950e468c
commit
65101d8c91
@@ -11,6 +11,8 @@
|
||||
#include <drm/drm_encoder.h>
|
||||
#include <drm/drm_gem_cma_helper.h>
|
||||
|
||||
#include "uapi/drm/vc4_drm.h"
|
||||
|
||||
/* Don't forget to update vc4_bo.c: bo_type_names[] when adding to
|
||||
* this.
|
||||
*/
|
||||
@@ -29,6 +31,36 @@ enum vc4_kernel_bo_type {
|
||||
VC4_BO_TYPE_COUNT
|
||||
};
|
||||
|
||||
/* Performance monitor object. The perform lifetime is controlled by userspace
|
||||
* using perfmon related ioctls. A perfmon can be attached to a submit_cl
|
||||
* request, and when this is the case, HW perf counters will be activated just
|
||||
* before the submit_cl is submitted to the GPU and disabled when the job is
|
||||
* done. This way, only events related to a specific job will be counted.
|
||||
*/
|
||||
struct vc4_perfmon {
|
||||
/* Tracks the number of users of the perfmon, when this counter reaches
|
||||
* zero the perfmon is destroyed.
|
||||
*/
|
||||
refcount_t refcnt;
|
||||
|
||||
/* Number of counters activated in this perfmon instance
|
||||
* (should be less than DRM_VC4_MAX_PERF_COUNTERS).
|
||||
*/
|
||||
u8 ncounters;
|
||||
|
||||
/* Events counted by the HW perf counters. */
|
||||
u8 events[DRM_VC4_MAX_PERF_COUNTERS];
|
||||
|
||||
/* Storage for counter values. Counters are incremented by the HW
|
||||
* perf counter values every time the perfmon is attached to a GPU job.
|
||||
* This way, perfmon users don't have to retrieve the results after
|
||||
* each job if they want to track events covering several submissions.
|
||||
* Note that counter values can't be reset, but you can fake a reset by
|
||||
* destroying the perfmon and creating a new one.
|
||||
*/
|
||||
u64 counters[0];
|
||||
};
|
||||
|
||||
struct vc4_dev {
|
||||
struct drm_device *dev;
|
||||
|
||||
@@ -121,6 +153,11 @@ struct vc4_dev {
|
||||
wait_queue_head_t job_wait_queue;
|
||||
struct work_struct job_done_work;
|
||||
|
||||
/* Used to track the active perfmon if any. Access to this field is
|
||||
* protected by job_lock.
|
||||
*/
|
||||
struct vc4_perfmon *active_perfmon;
|
||||
|
||||
/* List of struct vc4_seqno_cb for callbacks to be made from a
|
||||
* workqueue when the given seqno is passed.
|
||||
*/
|
||||
@@ -406,6 +443,21 @@ struct vc4_exec_info {
|
||||
void *uniforms_v;
|
||||
uint32_t uniforms_p;
|
||||
uint32_t uniforms_size;
|
||||
|
||||
/* Pointer to a performance monitor object if the user requested it,
|
||||
* NULL otherwise.
|
||||
*/
|
||||
struct vc4_perfmon *perfmon;
|
||||
};
|
||||
|
||||
/* Per-open file private data. Any driver-specific resource that has to be
|
||||
* released when the DRM file is closed should be placed here.
|
||||
*/
|
||||
struct vc4_file {
|
||||
struct {
|
||||
struct idr idr;
|
||||
struct mutex lock;
|
||||
} perfmon;
|
||||
};
|
||||
|
||||
static inline struct vc4_exec_info *
|
||||
@@ -646,3 +698,19 @@ bool vc4_check_tex_size(struct vc4_exec_info *exec,
|
||||
/* vc4_validate_shader.c */
|
||||
struct vc4_validated_shader_info *
|
||||
vc4_validate_shader(struct drm_gem_cma_object *shader_obj);
|
||||
|
||||
/* vc4_perfmon.c */
|
||||
void vc4_perfmon_get(struct vc4_perfmon *perfmon);
|
||||
void vc4_perfmon_put(struct vc4_perfmon *perfmon);
|
||||
void vc4_perfmon_start(struct vc4_dev *vc4, struct vc4_perfmon *perfmon);
|
||||
void vc4_perfmon_stop(struct vc4_dev *vc4, struct vc4_perfmon *perfmon,
|
||||
bool capture);
|
||||
struct vc4_perfmon *vc4_perfmon_find(struct vc4_file *vc4file, int id);
|
||||
void vc4_perfmon_open_file(struct vc4_file *vc4file);
|
||||
void vc4_perfmon_close_file(struct vc4_file *vc4file);
|
||||
int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int vc4_perfmon_destroy_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int vc4_perfmon_get_values_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
|
Reference in New Issue
Block a user