Skip to content

Commit 90f45c4

Browse files
committed
drm/msm: Add SYSPROF param (v2)
Add a SYSPROF param for system profiling tools like Mesa's pps-producer (perfetto) to control behavior related to system-wide performance counter collection. In particular, for profiling, one wants to ensure that GPU context switches do not effect perfcounter state, and might want to suppress suspend (which would cause counters to lose state). v2: Swap the order in msm_file_private_set_sysprof() [sboyd] and initialize the sysprof_active refcount to one (because the under/ overflow checking in refcount_t doesn't expect a 0->1 transition) meaning that values greater than 1 means sysprof is active. Signed-off-by: Rob Clark <robdclark@chromium.org> Link: https://lore.kernel.org/r/20220304005317.776110-4-robdclark@gmail.com
1 parent f7ddbf5 commit 90f45c4

6 files changed

Lines changed: 81 additions & 0 deletions

File tree

drivers/gpu/drm/msm/adreno/adreno_gpu.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
287287
uint32_t param, uint64_t value)
288288
{
289289
switch (param) {
290+
case MSM_PARAM_SYSPROF:
291+
if (!capable(CAP_SYS_ADMIN))
292+
return -EPERM;
293+
return msm_file_private_set_sysprof(ctx, gpu, value);
290294
default:
291295
DBG("%s: invalid param: %u", gpu->name, param);
292296
return -EINVAL;

drivers/gpu/drm/msm/msm_drv.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,16 @@ static void context_close(struct msm_file_private *ctx)
558558

559559
static void msm_postclose(struct drm_device *dev, struct drm_file *file)
560560
{
561+
struct msm_drm_private *priv = dev->dev_private;
561562
struct msm_file_private *ctx = file->driver_priv;
562563

564+
/*
565+
* It is not possible to set sysprof param to non-zero if gpu
566+
* is not initialized:
567+
*/
568+
if (priv->gpu)
569+
msm_file_private_set_sysprof(ctx, priv->gpu, 0);
570+
563571
context_close(ctx);
564572
}
565573

drivers/gpu/drm/msm/msm_gpu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
959959

960960
gpu->nr_rings = nr_rings;
961961

962+
refcount_set(&gpu->sysprof_active, 1);
963+
962964
return 0;
963965

964966
fail:

drivers/gpu/drm/msm/msm_gpu.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,13 @@ struct msm_gpu {
159159
struct msm_ringbuffer *rb[MSM_GPU_MAX_RINGS];
160160
int nr_rings;
161161

162+
/**
163+
* sysprof_active:
164+
*
165+
* The count of contexts that have enabled system profiling.
166+
*/
167+
refcount_t sysprof_active;
168+
162169
/**
163170
* cur_ctx_seqno:
164171
*
@@ -329,6 +336,24 @@ struct msm_file_private {
329336
struct kref ref;
330337
int seqno;
331338

339+
/**
340+
* sysprof:
341+
*
342+
* The value of MSM_PARAM_SYSPROF set by userspace. This is
343+
* intended to be used by system profiling tools like Mesa's
344+
* pps-producer (perfetto), and restricted to CAP_SYS_ADMIN.
345+
*
346+
* Setting a value of 1 will preserve performance counters across
347+
* context switches. Setting a value of 2 will in addition
348+
* suppress suspend. (Performance counters lose state across
349+
* power collapse, which is undesirable for profiling in some
350+
* cases.)
351+
*
352+
* The value automatically reverts to zero when the drm device
353+
* file is closed.
354+
*/
355+
int sysprof;
356+
332357
/**
333358
* entities:
334359
*
@@ -525,6 +550,8 @@ void msm_submitqueue_close(struct msm_file_private *ctx);
525550

526551
void msm_submitqueue_destroy(struct kref *kref);
527552

553+
int msm_file_private_set_sysprof(struct msm_file_private *ctx,
554+
struct msm_gpu *gpu, int sysprof);
528555
void __msm_file_private_destroy(struct kref *kref);
529556

530557
static inline void msm_file_private_put(struct msm_file_private *ctx)

drivers/gpu/drm/msm/msm_submitqueue.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,45 @@
77

88
#include "msm_gpu.h"
99

10+
int msm_file_private_set_sysprof(struct msm_file_private *ctx,
11+
struct msm_gpu *gpu, int sysprof)
12+
{
13+
/*
14+
* Since pm_runtime and sysprof_active are both refcounts, we
15+
* call apply the new value first, and then unwind the previous
16+
* value
17+
*/
18+
19+
switch (sysprof) {
20+
default:
21+
return -EINVAL;
22+
case 2:
23+
pm_runtime_get_sync(&gpu->pdev->dev);
24+
fallthrough;
25+
case 1:
26+
refcount_inc(&gpu->sysprof_active);
27+
fallthrough;
28+
case 0:
29+
break;
30+
}
31+
32+
/* unwind old value: */
33+
switch (ctx->sysprof) {
34+
case 2:
35+
pm_runtime_put_autosuspend(&gpu->pdev->dev);
36+
fallthrough;
37+
case 1:
38+
refcount_dec(&gpu->sysprof_active);
39+
fallthrough;
40+
case 0:
41+
break;
42+
}
43+
44+
ctx->sysprof = sysprof;
45+
46+
return 0;
47+
}
48+
1049
void __msm_file_private_destroy(struct kref *kref)
1150
{
1251
struct msm_file_private *ctx = container_of(kref,

include/uapi/drm/msm_drm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct drm_msm_timespec {
8181
#define MSM_PARAM_PP_PGTABLE 0x08 /* RO: Deprecated, always returns zero */
8282
#define MSM_PARAM_FAULTS 0x09 /* RO */
8383
#define MSM_PARAM_SUSPENDS 0x0a /* RO */
84+
#define MSM_PARAM_SYSPROF 0x0b /* WO: 1 preserves perfcntrs, 2 also disables suspend */
8485

8586
/* For backwards compat. The original support for preemption was based on
8687
* a single ring per priority level so # of priority levels equals the #

0 commit comments

Comments
 (0)