Skip to content

Commit f94c8e9

Browse files
vsbelgaumSasha Levin
authored andcommitted
drm/xe: Add locks in gtidle code
[ Upstream commit d160dc6 ] The update of the residency values needs to be protected by a lock to avoid multiple entrypoints, for example when multiple userspace clients read the sysfs file. Other in-kernel clients are going to be added to sample these values, making the problem worse. Protect those updates with a raw_spinlock so it can be called by future integration with perf pmu. Suggested-by: Lucas De Marchi <[email protected]> Cc: Rodrigo Vivi <[email protected]> Cc: Lucas De Marchi <[email protected]> Signed-off-by: Vinay Belgaumkar <[email protected]> Reviewed-by: Lucas De Marchi <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Lucas De Marchi <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 1e9d09b commit f94c8e9

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

drivers/gpu/drm/xe/xe_gt_idle.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ static u64 get_residency_ms(struct xe_gt_idle *gtidle, u64 cur_residency)
6969
{
7070
u64 delta, overflow_residency, prev_residency;
7171

72+
lockdep_assert_held(&gtidle->lock);
73+
7274
overflow_residency = BIT_ULL(32);
7375

7476
/*
@@ -275,8 +277,21 @@ static ssize_t idle_status_show(struct device *dev,
275277

276278
return sysfs_emit(buff, "%s\n", gt_idle_state_to_string(state));
277279
}
278-
static DEVICE_ATTR_RO(idle_status);
279280

281+
u64 xe_gt_idle_residency_msec(struct xe_gt_idle *gtidle)
282+
{
283+
struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
284+
u64 residency;
285+
unsigned long flags;
286+
287+
raw_spin_lock_irqsave(&gtidle->lock, flags);
288+
residency = get_residency_ms(gtidle, gtidle->idle_residency(pc));
289+
raw_spin_unlock_irqrestore(&gtidle->lock, flags);
290+
291+
return residency;
292+
}
293+
294+
static DEVICE_ATTR_RO(idle_status);
280295
static ssize_t idle_residency_ms_show(struct device *dev,
281296
struct device_attribute *attr, char *buff)
282297
{
@@ -285,10 +300,10 @@ static ssize_t idle_residency_ms_show(struct device *dev,
285300
u64 residency;
286301

287302
xe_pm_runtime_get(pc_to_xe(pc));
288-
residency = gtidle->idle_residency(pc);
303+
residency = xe_gt_idle_residency_msec(gtidle);
289304
xe_pm_runtime_put(pc_to_xe(pc));
290305

291-
return sysfs_emit(buff, "%llu\n", get_residency_ms(gtidle, residency));
306+
return sysfs_emit(buff, "%llu\n", residency);
292307
}
293308
static DEVICE_ATTR_RO(idle_residency_ms);
294309

@@ -331,6 +346,8 @@ int xe_gt_idle_init(struct xe_gt_idle *gtidle)
331346
if (!kobj)
332347
return -ENOMEM;
333348

349+
raw_spin_lock_init(&gtidle->lock);
350+
334351
if (xe_gt_is_media_type(gt)) {
335352
snprintf(gtidle->name, sizeof(gtidle->name), "gt%d-mc", gt->info.id);
336353
gtidle->idle_residency = xe_guc_pc_mc6_residency;

drivers/gpu/drm/xe/xe_gt_idle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ void xe_gt_idle_disable_c6(struct xe_gt *gt);
1717
void xe_gt_idle_enable_pg(struct xe_gt *gt);
1818
void xe_gt_idle_disable_pg(struct xe_gt *gt);
1919
int xe_gt_idle_pg_print(struct xe_gt *gt, struct drm_printer *p);
20+
u64 xe_gt_idle_residency_msec(struct xe_gt_idle *gtidle);
2021

2122
#endif /* _XE_GT_IDLE_H_ */

drivers/gpu/drm/xe/xe_gt_idle_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef _XE_GT_IDLE_SYSFS_TYPES_H_
77
#define _XE_GT_IDLE_SYSFS_TYPES_H_
88

9+
#include <linux/spinlock.h>
910
#include <linux/types.h>
1011

1112
struct xe_guc_pc;
@@ -31,6 +32,8 @@ struct xe_gt_idle {
3132
u64 cur_residency;
3233
/** @prev_residency: previous residency counter */
3334
u64 prev_residency;
35+
/** @lock: Lock protecting idle residency counters */
36+
raw_spinlock_t lock;
3437
/** @idle_status: get the current idle state */
3538
enum xe_gt_idle_state (*idle_status)(struct xe_guc_pc *pc);
3639
/** @idle_residency: get idle residency counter */

0 commit comments

Comments
 (0)