Skip to content

Commit ba02fd6

Browse files
Kevin Wangalexdeucher
authored andcommitted
drm/amdgpu: fix device attribute node create failed with multi gpu
the origin design will use varible of "attr->states" to save node supported states on current gpu device, but for multi gpu device, when probe second gpu device, the driver will check attribute node states from previous gpu device wthether to create attribute node. it will cause other gpu device create attribute node faild. 1. add member attr_list into amdgpu_device to link supported device attribute node. 2. add new structure "struct amdgpu_device_attr_entry{}" to track device attribute state. 3. drop member "states" from amdgpu_device_attr. v2: 1. move "attr_list" into amdgpu_pm and rename to "pm_attr_list". 2. refine create & remove device node functions parameter. fix: drm/amdgpu: optimize amdgpu device attribute code Signed-off-by: Kevin Wang <[email protected]> Reviewed-by: Alex Deucher <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 90ca78d commit ba02fd6

File tree

3 files changed

+58
-41
lines changed

3 files changed

+58
-41
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ struct amdgpu_pm {
450450

451451
/* Used for I2C access to various EEPROMs on relevant ASICs */
452452
struct i2c_adapter smu_i2c;
453+
struct list_head pm_attr_list;
453454
};
454455

455456
#define R600_SSTU_DFLT 0

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,50 +1725,50 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = {
17251725
};
17261726

17271727
static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
1728-
uint32_t mask)
1728+
uint32_t mask, enum amdgpu_device_attr_states *states)
17291729
{
17301730
struct device_attribute *dev_attr = &attr->dev_attr;
17311731
const char *attr_name = dev_attr->attr.name;
17321732
struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
17331733
enum amd_asic_type asic_type = adev->asic_type;
17341734

17351735
if (!(attr->flags & mask)) {
1736-
attr->states = ATTR_STATE_UNSUPPORTED;
1736+
*states = ATTR_STATE_UNSUPPORTED;
17371737
return 0;
17381738
}
17391739

17401740
#define DEVICE_ATTR_IS(_name) (!strcmp(attr_name, #_name))
17411741

17421742
if (DEVICE_ATTR_IS(pp_dpm_socclk)) {
17431743
if (asic_type < CHIP_VEGA10)
1744-
attr->states = ATTR_STATE_UNSUPPORTED;
1744+
*states = ATTR_STATE_UNSUPPORTED;
17451745
} else if (DEVICE_ATTR_IS(pp_dpm_dcefclk)) {
17461746
if (asic_type < CHIP_VEGA10 || asic_type == CHIP_ARCTURUS)
1747-
attr->states = ATTR_STATE_UNSUPPORTED;
1747+
*states = ATTR_STATE_UNSUPPORTED;
17481748
} else if (DEVICE_ATTR_IS(pp_dpm_fclk)) {
17491749
if (asic_type < CHIP_VEGA20)
1750-
attr->states = ATTR_STATE_UNSUPPORTED;
1750+
*states = ATTR_STATE_UNSUPPORTED;
17511751
} else if (DEVICE_ATTR_IS(pp_dpm_pcie)) {
17521752
if (asic_type == CHIP_ARCTURUS)
1753-
attr->states = ATTR_STATE_UNSUPPORTED;
1753+
*states = ATTR_STATE_UNSUPPORTED;
17541754
} else if (DEVICE_ATTR_IS(pp_od_clk_voltage)) {
1755-
attr->states = ATTR_STATE_UNSUPPORTED;
1755+
*states = ATTR_STATE_UNSUPPORTED;
17561756
if ((is_support_sw_smu(adev) && adev->smu.od_enabled) ||
17571757
(!is_support_sw_smu(adev) && hwmgr->od_enabled))
1758-
attr->states = ATTR_STATE_SUPPORTED;
1758+
*states = ATTR_STATE_SUPPORTED;
17591759
} else if (DEVICE_ATTR_IS(mem_busy_percent)) {
17601760
if (adev->flags & AMD_IS_APU || asic_type == CHIP_VEGA10)
1761-
attr->states = ATTR_STATE_UNSUPPORTED;
1761+
*states = ATTR_STATE_UNSUPPORTED;
17621762
} else if (DEVICE_ATTR_IS(pcie_bw)) {
17631763
/* PCIe Perf counters won't work on APU nodes */
17641764
if (adev->flags & AMD_IS_APU)
1765-
attr->states = ATTR_STATE_UNSUPPORTED;
1765+
*states = ATTR_STATE_UNSUPPORTED;
17661766
} else if (DEVICE_ATTR_IS(unique_id)) {
17671767
if (!adev->unique_id)
1768-
attr->states = ATTR_STATE_UNSUPPORTED;
1768+
*states = ATTR_STATE_UNSUPPORTED;
17691769
} else if (DEVICE_ATTR_IS(pp_features)) {
17701770
if (adev->flags & AMD_IS_APU || asic_type < CHIP_VEGA10)
1771-
attr->states = ATTR_STATE_UNSUPPORTED;
1771+
*states = ATTR_STATE_UNSUPPORTED;
17721772
}
17731773

17741774
if (asic_type == CHIP_ARCTURUS) {
@@ -1789,27 +1789,29 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_
17891789

17901790
static int amdgpu_device_attr_create(struct amdgpu_device *adev,
17911791
struct amdgpu_device_attr *attr,
1792-
uint32_t mask)
1792+
uint32_t mask, struct list_head *attr_list)
17931793
{
17941794
int ret = 0;
17951795
struct device_attribute *dev_attr = &attr->dev_attr;
17961796
const char *name = dev_attr->attr.name;
1797+
enum amdgpu_device_attr_states attr_states = ATTR_STATE_SUPPORTED;
1798+
struct amdgpu_device_attr_entry *attr_entry;
1799+
17971800
int (*attr_update)(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
1798-
uint32_t mask) = default_attr_update;
1801+
uint32_t mask, enum amdgpu_device_attr_states *states) = default_attr_update;
17991802

18001803
BUG_ON(!attr);
18011804

18021805
attr_update = attr->attr_update ? attr_update : default_attr_update;
18031806

1804-
ret = attr_update(adev, attr, mask);
1807+
ret = attr_update(adev, attr, mask, &attr_states);
18051808
if (ret) {
18061809
dev_err(adev->dev, "failed to update device file %s, ret = %d\n",
18071810
name, ret);
18081811
return ret;
18091812
}
18101813

1811-
/* the attr->states maybe changed after call attr->attr_update function */
1812-
if (attr->states == ATTR_STATE_UNSUPPORTED)
1814+
if (attr_states == ATTR_STATE_UNSUPPORTED)
18131815
return 0;
18141816

18151817
ret = device_create_file(adev->dev, dev_attr);
@@ -1818,7 +1820,14 @@ static int amdgpu_device_attr_create(struct amdgpu_device *adev,
18181820
name, ret);
18191821
}
18201822

1821-
attr->states = ATTR_STATE_SUPPORTED;
1823+
attr_entry = kmalloc(sizeof(*attr_entry), GFP_KERNEL);
1824+
if (!attr_entry)
1825+
return -ENOMEM;
1826+
1827+
attr_entry->attr = attr;
1828+
INIT_LIST_HEAD(&attr_entry->entry);
1829+
1830+
list_add_tail(&attr_entry->entry, attr_list);
18221831

18231832
return ret;
18241833
}
@@ -1827,45 +1836,48 @@ static void amdgpu_device_attr_remove(struct amdgpu_device *adev, struct amdgpu_
18271836
{
18281837
struct device_attribute *dev_attr = &attr->dev_attr;
18291838

1830-
if (attr->states == ATTR_STATE_UNSUPPORTED)
1831-
return;
1832-
18331839
device_remove_file(adev->dev, dev_attr);
1834-
1835-
attr->states = ATTR_STATE_UNSUPPORTED;
18361840
}
18371841

1842+
static void amdgpu_device_attr_remove_groups(struct amdgpu_device *adev,
1843+
struct list_head *attr_list);
1844+
18381845
static int amdgpu_device_attr_create_groups(struct amdgpu_device *adev,
18391846
struct amdgpu_device_attr *attrs,
18401847
uint32_t counts,
1841-
uint32_t mask)
1848+
uint32_t mask,
1849+
struct list_head *attr_list)
18421850
{
18431851
int ret = 0;
18441852
uint32_t i = 0;
18451853

18461854
for (i = 0; i < counts; i++) {
1847-
ret = amdgpu_device_attr_create(adev, &attrs[i], mask);
1855+
ret = amdgpu_device_attr_create(adev, &attrs[i], mask, attr_list);
18481856
if (ret)
18491857
goto failed;
18501858
}
18511859

18521860
return 0;
18531861

18541862
failed:
1855-
while (i--)
1856-
amdgpu_device_attr_remove(adev, &attrs[i]);
1863+
amdgpu_device_attr_remove_groups(adev, attr_list);
18571864

18581865
return ret;
18591866
}
18601867

18611868
static void amdgpu_device_attr_remove_groups(struct amdgpu_device *adev,
1862-
struct amdgpu_device_attr *attrs,
1863-
uint32_t counts)
1869+
struct list_head *attr_list)
18641870
{
1865-
uint32_t i = 0;
1871+
struct amdgpu_device_attr_entry *entry, *entry_tmp;
18661872

1867-
for (i = 0; i < counts; i++)
1868-
amdgpu_device_attr_remove(adev, &attrs[i]);
1873+
if (list_empty(attr_list))
1874+
return ;
1875+
1876+
list_for_each_entry_safe(entry, entry_tmp, attr_list, entry) {
1877+
amdgpu_device_attr_remove(adev, entry->attr);
1878+
list_del(&entry->entry);
1879+
kfree(entry);
1880+
}
18691881
}
18701882

18711883
static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
@@ -3276,6 +3288,8 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
32763288
if (adev->pm.dpm_enabled == 0)
32773289
return 0;
32783290

3291+
INIT_LIST_HEAD(&adev->pm.pm_attr_list);
3292+
32793293
adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev,
32803294
DRIVER_NAME, adev,
32813295
hwmon_groups);
@@ -3302,7 +3316,8 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
33023316
ret = amdgpu_device_attr_create_groups(adev,
33033317
amdgpu_device_attrs,
33043318
ARRAY_SIZE(amdgpu_device_attrs),
3305-
mask);
3319+
mask,
3320+
&adev->pm.pm_attr_list);
33063321
if (ret)
33073322
return ret;
33083323

@@ -3319,9 +3334,7 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
33193334
if (adev->pm.int_hwmon_dev)
33203335
hwmon_device_unregister(adev->pm.int_hwmon_dev);
33213336

3322-
amdgpu_device_attr_remove_groups(adev,
3323-
amdgpu_device_attrs,
3324-
ARRAY_SIZE(amdgpu_device_attrs));
3337+
amdgpu_device_attr_remove_groups(adev, &adev->pm.pm_attr_list);
33253338
}
33263339

33273340
void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)

drivers/gpu/drm/amd/amdgpu/amdgpu_pm.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,14 @@ enum amdgpu_device_attr_states {
4747
struct amdgpu_device_attr {
4848
struct device_attribute dev_attr;
4949
enum amdgpu_device_attr_flags flags;
50-
enum amdgpu_device_attr_states states;
51-
int (*attr_update)(struct amdgpu_device *adev,
52-
struct amdgpu_device_attr* attr,
53-
uint32_t mask);
50+
int (*attr_update)(struct amdgpu_device *adev, struct amdgpu_device_attr *attr,
51+
uint32_t mask, enum amdgpu_device_attr_states *states);
52+
53+
};
54+
55+
struct amdgpu_device_attr_entry {
56+
struct list_head entry;
57+
struct amdgpu_device_attr *attr;
5458
};
5559

5660
#define to_amdgpu_device_attr(_dev_attr) \
@@ -59,7 +63,6 @@ struct amdgpu_device_attr {
5963
#define __AMDGPU_DEVICE_ATTR(_name, _mode, _show, _store, _flags, ...) \
6064
{ .dev_attr = __ATTR(_name, _mode, _show, _store), \
6165
.flags = _flags, \
62-
.states = ATTR_STATE_SUPPORTED, \
6366
##__VA_ARGS__, }
6467

6568
#define AMDGPU_DEVICE_ATTR(_name, _mode, _flags, ...) \

0 commit comments

Comments
 (0)