Skip to content

Commit 727bf2d

Browse files
committed
Merge tag 'drm-xe-next-2025-11-14' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next
Driver Changes: Avoid TOCTOU when montoring throttle reasons (Lucas) Add/extend workaround (Nitin) SRIOV migration work / plumbing (Michal Wajdeczko, Michal Winiarski, Lukasz) Drop debug flag requirement for VF resource fixup Fix MTL vm_max_level (Rodrigo) Changes around TILE_ADDR_RANGE for platform compatibility (Fei, Lucas) Add runtime registers for GFX ver >= 35 (Piotr) Kerneldoc fix (Kriish) Rework pcode error mapping (Lucas) Allow lockdown the PF (Michal) Eliminate GUC code caching of some frequency values (Sk) Improvements around forcewake referencing (Matt Roper) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Hellstrom <thomas.hellstrom@linux.intel.com> Link: https://patch.msgid.link/aRcJOrisG2qPbucE@fedora
2 parents 61926c9 + 6bcb180 commit 727bf2d

55 files changed

Lines changed: 3986 additions & 438 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

drivers/gpu/drm/xe/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,11 @@ xe-$(CONFIG_PCI_IOV) += \
174174
xe_lmtt_2l.o \
175175
xe_lmtt_ml.o \
176176
xe_pci_sriov.o \
177+
xe_sriov_packet.o \
177178
xe_sriov_pf.o \
178179
xe_sriov_pf_control.o \
179180
xe_sriov_pf_debugfs.o \
181+
xe_sriov_pf_migration.o \
180182
xe_sriov_pf_provision.o \
181183
xe_sriov_pf_service.o \
182184
xe_sriov_pf_sysfs.o \

drivers/gpu/drm/xe/regs/xe_gt_regs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@
101101

102102
#define XE2_LMEM_CFG XE_REG(0x48b0)
103103

104-
#define XEHP_TILE_ADDR_RANGE(_idx) XE_REG_MCR(0x4900 + (_idx) * 4)
105104
#define XEHP_FLAT_CCS_BASE_ADDR XE_REG_MCR(0x4910)
106105
#define XEHP_FLAT_CCS_PTR REG_GENMASK(31, 8)
107106

drivers/gpu/drm/xe/regs/xe_regs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
#define STOLEN_RESERVED XE_REG(0x1082c0)
4141
#define WOPCM_SIZE_MASK REG_GENMASK64(9, 7)
4242

43+
#define SG_TILE_ADDR_RANGE(_idx) XE_REG(0x1083a0 + (_idx) * 4)
44+
4345
#define MTL_RP_STATE_CAP XE_REG(0x138000)
4446

4547
#define MTL_GT_RPA_FREQUENCY XE_REG(0x138008)
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
// SPDX-License-Identifier: GPL-2.0 AND MIT
2+
/*
3+
* Copyright © 2025 Intel Corporation
4+
*/
5+
6+
#include <kunit/static_stub.h>
7+
#include <kunit/test.h>
8+
#include <kunit/test-bug.h>
9+
10+
#include "xe_kunit_helpers.h"
11+
#include "xe_pci_test.h"
12+
13+
#define TEST_MAX_VFS 63
14+
15+
static void pf_set_admin_mode(struct xe_device *xe, bool enable)
16+
{
17+
/* should match logic of xe_sriov_pf_admin_only() */
18+
xe->info.probe_display = !enable;
19+
KUNIT_EXPECT_EQ(kunit_get_current_test(), enable, xe_sriov_pf_admin_only(xe));
20+
}
21+
22+
static const void *num_vfs_gen_param(struct kunit *test, const void *prev, char *desc)
23+
{
24+
unsigned long next = 1 + (unsigned long)prev;
25+
26+
if (next > TEST_MAX_VFS)
27+
return NULL;
28+
snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%lu VF%s",
29+
next, str_plural(next));
30+
return (void *)next;
31+
}
32+
33+
static int pf_gt_config_test_init(struct kunit *test)
34+
{
35+
struct xe_pci_fake_data fake = {
36+
.sriov_mode = XE_SRIOV_MODE_PF,
37+
.platform = XE_TIGERLAKE, /* any random platform with SR-IOV */
38+
.subplatform = XE_SUBPLATFORM_NONE,
39+
};
40+
struct xe_device *xe;
41+
struct xe_gt *gt;
42+
43+
test->priv = &fake;
44+
xe_kunit_helper_xe_device_test_init(test);
45+
46+
xe = test->priv;
47+
KUNIT_ASSERT_TRUE(test, IS_SRIOV_PF(xe));
48+
49+
gt = xe_root_mmio_gt(xe);
50+
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, gt);
51+
test->priv = gt;
52+
53+
/* pretend it can support up to 63 VFs */
54+
xe->sriov.pf.device_total_vfs = TEST_MAX_VFS;
55+
xe->sriov.pf.driver_max_vfs = TEST_MAX_VFS;
56+
KUNIT_ASSERT_EQ(test, xe_sriov_pf_get_totalvfs(xe), 63);
57+
58+
pf_set_admin_mode(xe, false);
59+
KUNIT_ASSERT_EQ(test, xe_sriov_init(xe), 0);
60+
61+
/* more sanity checks */
62+
KUNIT_EXPECT_EQ(test, GUC_ID_MAX + 1, SZ_64K);
63+
KUNIT_EXPECT_EQ(test, GUC_NUM_DOORBELLS, SZ_256);
64+
65+
return 0;
66+
}
67+
68+
static void fair_contexts_1vf(struct kunit *test)
69+
{
70+
struct xe_gt *gt = test->priv;
71+
struct xe_device *xe = gt_to_xe(gt);
72+
73+
pf_set_admin_mode(xe, false);
74+
KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
75+
KUNIT_EXPECT_EQ(test, SZ_32K, pf_profile_fair_ctxs(gt, 1));
76+
77+
pf_set_admin_mode(xe, true);
78+
KUNIT_ASSERT_TRUE(test, xe_sriov_pf_admin_only(xe));
79+
KUNIT_EXPECT_EQ(test, SZ_64K - SZ_1K, pf_profile_fair_ctxs(gt, 1));
80+
}
81+
82+
static void fair_contexts(struct kunit *test)
83+
{
84+
unsigned int num_vfs = (unsigned long)test->param_value;
85+
struct xe_gt *gt = test->priv;
86+
struct xe_device *xe = gt_to_xe(gt);
87+
88+
pf_set_admin_mode(xe, false);
89+
KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
90+
91+
KUNIT_EXPECT_TRUE(test, is_power_of_2(pf_profile_fair_ctxs(gt, num_vfs)));
92+
KUNIT_EXPECT_GT(test, GUC_ID_MAX, num_vfs * pf_profile_fair_ctxs(gt, num_vfs));
93+
94+
if (num_vfs > 31)
95+
KUNIT_ASSERT_EQ(test, SZ_1K, pf_profile_fair_ctxs(gt, num_vfs));
96+
else if (num_vfs > 15)
97+
KUNIT_ASSERT_EQ(test, SZ_2K, pf_profile_fair_ctxs(gt, num_vfs));
98+
else if (num_vfs > 7)
99+
KUNIT_ASSERT_EQ(test, SZ_4K, pf_profile_fair_ctxs(gt, num_vfs));
100+
else if (num_vfs > 3)
101+
KUNIT_ASSERT_EQ(test, SZ_8K, pf_profile_fair_ctxs(gt, num_vfs));
102+
else if (num_vfs > 1)
103+
KUNIT_ASSERT_EQ(test, SZ_16K, pf_profile_fair_ctxs(gt, num_vfs));
104+
else
105+
KUNIT_ASSERT_EQ(test, SZ_32K, pf_profile_fair_ctxs(gt, num_vfs));
106+
}
107+
108+
static void fair_doorbells_1vf(struct kunit *test)
109+
{
110+
struct xe_gt *gt = test->priv;
111+
struct xe_device *xe = gt_to_xe(gt);
112+
113+
pf_set_admin_mode(xe, false);
114+
KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
115+
KUNIT_EXPECT_EQ(test, 128, pf_profile_fair_dbs(gt, 1));
116+
117+
pf_set_admin_mode(xe, true);
118+
KUNIT_ASSERT_TRUE(test, xe_sriov_pf_admin_only(xe));
119+
KUNIT_EXPECT_EQ(test, 240, pf_profile_fair_dbs(gt, 1));
120+
}
121+
122+
static void fair_doorbells(struct kunit *test)
123+
{
124+
unsigned int num_vfs = (unsigned long)test->param_value;
125+
struct xe_gt *gt = test->priv;
126+
struct xe_device *xe = gt_to_xe(gt);
127+
128+
pf_set_admin_mode(xe, false);
129+
KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
130+
131+
KUNIT_EXPECT_TRUE(test, is_power_of_2(pf_profile_fair_dbs(gt, num_vfs)));
132+
KUNIT_EXPECT_GE(test, GUC_NUM_DOORBELLS, (num_vfs + 1) * pf_profile_fair_dbs(gt, num_vfs));
133+
134+
if (num_vfs > 31)
135+
KUNIT_ASSERT_EQ(test, SZ_4, pf_profile_fair_dbs(gt, num_vfs));
136+
else if (num_vfs > 15)
137+
KUNIT_ASSERT_EQ(test, SZ_8, pf_profile_fair_dbs(gt, num_vfs));
138+
else if (num_vfs > 7)
139+
KUNIT_ASSERT_EQ(test, SZ_16, pf_profile_fair_dbs(gt, num_vfs));
140+
else if (num_vfs > 3)
141+
KUNIT_ASSERT_EQ(test, SZ_32, pf_profile_fair_dbs(gt, num_vfs));
142+
else if (num_vfs > 1)
143+
KUNIT_ASSERT_EQ(test, SZ_64, pf_profile_fair_dbs(gt, num_vfs));
144+
else
145+
KUNIT_ASSERT_EQ(test, SZ_128, pf_profile_fair_dbs(gt, num_vfs));
146+
}
147+
148+
static void fair_ggtt_1vf(struct kunit *test)
149+
{
150+
struct xe_gt *gt = test->priv;
151+
struct xe_device *xe = gt_to_xe(gt);
152+
153+
pf_set_admin_mode(xe, false);
154+
KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
155+
KUNIT_EXPECT_EQ(test, SZ_2G, pf_profile_fair_ggtt(gt, 1));
156+
157+
pf_set_admin_mode(xe, true);
158+
KUNIT_ASSERT_TRUE(test, xe_sriov_pf_admin_only(xe));
159+
KUNIT_EXPECT_EQ(test, SZ_2G + SZ_1G + SZ_512M, pf_profile_fair_ggtt(gt, 1));
160+
}
161+
162+
static void fair_ggtt(struct kunit *test)
163+
{
164+
unsigned int num_vfs = (unsigned long)test->param_value;
165+
struct xe_gt *gt = test->priv;
166+
struct xe_device *xe = gt_to_xe(gt);
167+
u64 alignment = pf_get_ggtt_alignment(gt);
168+
u64 shareable = SZ_2G + SZ_1G + SZ_512M;
169+
170+
pf_set_admin_mode(xe, false);
171+
KUNIT_ASSERT_FALSE(test, xe_sriov_pf_admin_only(xe));
172+
173+
KUNIT_EXPECT_TRUE(test, IS_ALIGNED(pf_profile_fair_ggtt(gt, num_vfs), alignment));
174+
KUNIT_EXPECT_GE(test, shareable, num_vfs * pf_profile_fair_ggtt(gt, num_vfs));
175+
176+
if (num_vfs > 56)
177+
KUNIT_ASSERT_EQ(test, SZ_64M - SZ_8M, pf_profile_fair_ggtt(gt, num_vfs));
178+
else if (num_vfs > 28)
179+
KUNIT_ASSERT_EQ(test, SZ_64M, pf_profile_fair_ggtt(gt, num_vfs));
180+
else if (num_vfs > 14)
181+
KUNIT_ASSERT_EQ(test, SZ_128M, pf_profile_fair_ggtt(gt, num_vfs));
182+
else if (num_vfs > 7)
183+
KUNIT_ASSERT_EQ(test, SZ_256M, pf_profile_fair_ggtt(gt, num_vfs));
184+
else if (num_vfs > 3)
185+
KUNIT_ASSERT_EQ(test, SZ_512M, pf_profile_fair_ggtt(gt, num_vfs));
186+
else if (num_vfs > 1)
187+
KUNIT_ASSERT_EQ(test, SZ_1G, pf_profile_fair_ggtt(gt, num_vfs));
188+
else
189+
KUNIT_ASSERT_EQ(test, SZ_2G, pf_profile_fair_ggtt(gt, num_vfs));
190+
}
191+
192+
static struct kunit_case pf_gt_config_test_cases[] = {
193+
KUNIT_CASE(fair_contexts_1vf),
194+
KUNIT_CASE(fair_doorbells_1vf),
195+
KUNIT_CASE(fair_ggtt_1vf),
196+
KUNIT_CASE_PARAM(fair_contexts, num_vfs_gen_param),
197+
KUNIT_CASE_PARAM(fair_doorbells, num_vfs_gen_param),
198+
KUNIT_CASE_PARAM(fair_ggtt, num_vfs_gen_param),
199+
{}
200+
};
201+
202+
static struct kunit_suite pf_gt_config_suite = {
203+
.name = "pf_gt_config",
204+
.test_cases = pf_gt_config_test_cases,
205+
.init = pf_gt_config_test_init,
206+
};
207+
208+
kunit_test_suite(pf_gt_config_suite);

drivers/gpu/drm/xe/xe_eu_stall.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ struct xe_eu_stall_data_stream {
4949
wait_queue_head_t poll_wq;
5050
size_t data_record_size;
5151
size_t per_xecore_buf_size;
52+
unsigned int fw_ref;
5253

5354
struct xe_gt *gt;
5455
struct xe_bo *bo;
@@ -660,13 +661,12 @@ static int xe_eu_stall_stream_enable(struct xe_eu_stall_data_stream *stream)
660661
struct per_xecore_buf *xecore_buf;
661662
struct xe_gt *gt = stream->gt;
662663
u16 group, instance;
663-
unsigned int fw_ref;
664664
int xecore;
665665

666666
/* Take runtime pm ref and forcewake to disable RC6 */
667667
xe_pm_runtime_get(gt_to_xe(gt));
668-
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_RENDER);
669-
if (!xe_force_wake_ref_has_domain(fw_ref, XE_FW_RENDER)) {
668+
stream->fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_RENDER);
669+
if (!xe_force_wake_ref_has_domain(stream->fw_ref, XE_FW_RENDER)) {
670670
xe_gt_err(gt, "Failed to get RENDER forcewake\n");
671671
xe_pm_runtime_put(gt_to_xe(gt));
672672
return -ETIMEDOUT;
@@ -832,7 +832,7 @@ static int xe_eu_stall_disable_locked(struct xe_eu_stall_data_stream *stream)
832832
xe_gt_mcr_multicast_write(gt, ROW_CHICKEN2,
833833
_MASKED_BIT_DISABLE(DISABLE_DOP_GATING));
834834

835-
xe_force_wake_put(gt_to_fw(gt), XE_FW_RENDER);
835+
xe_force_wake_put(gt_to_fw(gt), stream->fw_ref);
836836
xe_pm_runtime_put(gt_to_xe(gt));
837837

838838
return 0;

drivers/gpu/drm/xe/xe_force_wake_types.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,22 @@ enum xe_force_wake_domains {
5252
};
5353

5454
/**
55-
* struct xe_force_wake_domain - Xe force wake domains
55+
* struct xe_force_wake_domain - Xe force wake power domain
56+
*
57+
* Represents an individual device-internal power domain. The driver must
58+
* ensure the power domain is awake before accessing registers or other
59+
* hardware functionality that is part of the power domain. Since different
60+
* driver threads may access hardware units simultaneously, a reference count
61+
* is used to ensure that the domain remains awake as long as any software
62+
* is using the part of the hardware covered by the power domain.
63+
*
64+
* Hardware provides a register interface to allow the driver to request
65+
* wake/sleep of power domains, although in most cases the actual action of
66+
* powering the hardware up/down is handled by firmware (and may be subject to
67+
* requirements and constraints outside of the driver's visibility) so the
68+
* driver needs to wait for an acknowledgment that a wake request has been
69+
* acted upon before accessing the parts of the hardware that reside within the
70+
* power domain.
5671
*/
5772
struct xe_force_wake_domain {
5873
/** @id: domain force wake id */
@@ -70,7 +85,14 @@ struct xe_force_wake_domain {
7085
};
7186

7287
/**
73-
* struct xe_force_wake - Xe force wake
88+
* struct xe_force_wake - Xe force wake collection
89+
*
90+
* Represents a collection of related power domains (struct
91+
* xe_force_wake_domain) associated with a subunit of the device.
92+
*
93+
* Currently only used for GT power domains (where the term "forcewake" is used
94+
* in the hardware documentation), although the interface could be extended to
95+
* power wells in other parts of the hardware in the future.
7496
*/
7597
struct xe_force_wake {
7698
/** @gt: back pointers to GT */

0 commit comments

Comments
 (0)