summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 2a6cf7963dde..c0336ca9bf6a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -237,8 +237,13 @@ static int amdgpu_check_address_validity(struct amdgpu_device *adev,
(address >= RAS_UMC_INJECT_ADDR_LIMIT))
return -EFAULT;
- count = amdgpu_umc_lookup_bad_pages_in_a_row(adev,
+ if (amdgpu_uniras_enabled(adev))
+ count = amdgpu_ras_mgr_lookup_bad_pages_in_a_row(adev, address,
+ page_pfns, ARRAY_SIZE(page_pfns));
+ else
+ count = amdgpu_umc_lookup_bad_pages_in_a_row(adev,
address, page_pfns, ARRAY_SIZE(page_pfns));
+
if (count <= 0)
return -EPERM;
@@ -886,7 +891,7 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
if (head->block == AMDGPU_RAS_BLOCK__GFX &&
!amdgpu_sriov_vf(adev) &&
!amdgpu_ras_intr_triggered()) {
- info = kzalloc(sizeof(union ta_ras_cmd_input), GFP_KERNEL);
+ info = kzalloc_obj(union ta_ras_cmd_input);
if (!info)
return -ENOMEM;
@@ -1899,7 +1904,7 @@ static ssize_t amdgpu_ras_sysfs_badpages_read(struct file *f,
memset(buf, 0, count);
bps_count = end - start;
- bps = kmalloc_array(bps_count, sizeof(*bps), GFP_KERNEL);
+ bps = kmalloc_objs(*bps, bps_count);
if (!bps)
return 0;
@@ -1917,8 +1922,6 @@ static ssize_t amdgpu_ras_sysfs_badpages_read(struct file *f,
for (i = 0; i < bps_count; i++) {
address = ((uint64_t)bps[i].bp) << AMDGPU_GPU_PAGE_SHIFT;
- if (amdgpu_ras_check_critical_address(adev, address))
- continue;
bps[i].size = AMDGPU_GPU_PAGE_SIZE;
@@ -1931,6 +1934,10 @@ static ssize_t amdgpu_ras_sysfs_badpages_read(struct file *f,
else
bps[i].flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED;
+ if ((bps[i].flags != AMDGPU_RAS_RETIRE_PAGE_RESERVED) &&
+ amdgpu_ras_check_critical_address(adev, address))
+ bps[i].flags = AMDGPU_RAS_RETIRE_PAGE_RESERVED;
+
s += scnprintf(&buf[s], element_size + 1,
"0x%08x : 0x%08x : %1s\n",
bps[i].bp,
@@ -2777,6 +2784,10 @@ static int amdgpu_ras_badpages_read(struct amdgpu_device *adev,
if (!data->bps[i].ts)
continue;
+ /* U64_MAX is used to mark the record as invalid */
+ if (data->bps[i].retired_page == U64_MAX)
+ continue;
+
bps[r].bp = data->bps[i].retired_page;
r++;
if (r >= count)
@@ -2800,7 +2811,7 @@ static int amdgpu_uniras_badpages_read(struct amdgpu_device *adev,
if (!bps || !count)
return -EINVAL;
- output = kmalloc(sizeof(*output), GFP_KERNEL);
+ output = kmalloc_obj(*output);
if (!output)
return -ENOMEM;
@@ -2980,7 +2991,7 @@ static int amdgpu_ras_realloc_eh_data_space(struct amdgpu_device *adev,
unsigned int old_space = data->count + data->space_left;
unsigned int new_space = old_space + pages;
unsigned int align_space = ALIGN(new_space, 512);
- void *bps = kmalloc_array(align_space, sizeof(*data->bps), GFP_KERNEL);
+ void *bps = kmalloc_objs(*data->bps, align_space);
if (!bps) {
return -ENOMEM;
@@ -3076,18 +3087,20 @@ static int __amdgpu_ras_restore_bad_pages(struct amdgpu_device *adev,
struct ras_err_handler_data *data = con->eh_data;
for (j = 0; j < count; j++) {
+ if (!data->space_left &&
+ amdgpu_ras_realloc_eh_data_space(adev, data, 256)) {
+ return -ENOMEM;
+ }
+
if (amdgpu_ras_check_bad_page_unlock(con,
bps[j].retired_page << AMDGPU_GPU_PAGE_SHIFT)) {
+ /* set to U64_MAX to mark it as invalid */
+ data->bps[data->count].retired_page = U64_MAX;
data->count++;
data->space_left--;
continue;
}
- if (!data->space_left &&
- amdgpu_ras_realloc_eh_data_space(adev, data, 256)) {
- return -ENOMEM;
- }
-
amdgpu_ras_reserve_page(adev, bps[j].retired_page);
memcpy(&data->bps[data->count], &(bps[j]),
@@ -3225,8 +3238,8 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
if (from_rom) {
err_data.err_addr =
- kcalloc(adev->umc.retire_unit,
- sizeof(struct eeprom_table_record), GFP_KERNEL);
+ kzalloc_objs(struct eeprom_table_record,
+ adev->umc.retire_unit);
if (!err_data.err_addr) {
dev_warn(adev->dev, "Failed to alloc UMC error address record in mca2pa conversion!\n");
return -ENOMEM;
@@ -3249,8 +3262,6 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
/* deal with retire_unit records a time */
ret = __amdgpu_ras_convert_rec_array_from_rom(adev,
&bps[i], &err_data, nps);
- if (ret)
- con->bad_page_num -= adev->umc.retire_unit;
i += (adev->umc.retire_unit - 1);
} else {
break;
@@ -3263,8 +3274,6 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev,
for (; i < pages; i++) {
ret = __amdgpu_ras_convert_rec_from_rom(adev,
&bps[i], &err_data, nps);
- if (ret)
- con->bad_page_num -= adev->umc.retire_unit;
}
con->eh_data->count_saved = con->eh_data->count;
@@ -3366,7 +3375,7 @@ static int amdgpu_ras_load_bad_pages(struct amdgpu_device *adev)
if (control->ras_num_recs == 0 || amdgpu_bad_page_threshold == 0)
return 0;
- bps = kcalloc(control->ras_num_recs, sizeof(*bps), GFP_KERNEL);
+ bps = kzalloc_objs(*bps, control->ras_num_recs);
if (!bps)
return -ENOMEM;
@@ -3854,7 +3863,7 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev, bool init_bp_info)
return 0;
data = &con->eh_data;
- *data = kzalloc(sizeof(**data), GFP_KERNEL);
+ *data = kzalloc_obj(**data);
if (!*data) {
ret = -ENOMEM;
goto out;
@@ -4343,7 +4352,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev)
* to handle fatal error */
r = amdgpu_nbio_ras_sw_init(adev);
if (r)
- return r;
+ goto release_con;
if (adev->nbio.ras &&
adev->nbio.ras->init_ras_controller_interrupt) {
@@ -4421,10 +4430,10 @@ static int amdgpu_persistent_edc_harvesting(struct amdgpu_device *adev,
return 0;
if (amdgpu_ras_query_error_status(adev, &info) != 0)
- DRM_WARN("RAS init harvest failure");
+ drm_warn(adev_to_drm(adev), "RAS init query failure");
if (amdgpu_ras_reset_error_status(adev, ras_block->block) != 0)
- DRM_WARN("RAS init harvest reset failure");
+ drm_warn(adev_to_drm(adev), "RAS init harvest reset failure");
return 0;
}
@@ -4490,7 +4499,7 @@ int amdgpu_ras_block_late_init(struct amdgpu_device *adev,
/* Those are the cached values at init.
*/
- query_info = kzalloc(sizeof(*query_info), GFP_KERNEL);
+ query_info = kzalloc_obj(*query_info);
if (!query_info)
return -ENOMEM;
memcpy(&query_info->head, ras_block, sizeof(struct ras_common_if));
@@ -4641,6 +4650,8 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev)
amdgpu_ras_block_late_init_default(adev, &obj->ras_comm);
}
+ amdgpu_ras_check_bad_page_status(adev);
+
return 0;
}
@@ -5177,7 +5188,7 @@ int amdgpu_ras_register_ras_block(struct amdgpu_device *adev,
if (!adev || !ras_block_obj)
return -EINVAL;
- ras_node = kzalloc(sizeof(*ras_node), GFP_KERNEL);
+ ras_node = kzalloc_obj(*ras_node);
if (!ras_node)
return -ENOMEM;
@@ -5378,7 +5389,7 @@ static struct ras_err_node *amdgpu_ras_error_node_new(void)
{
struct ras_err_node *err_node;
- err_node = kvzalloc(sizeof(*err_node), GFP_KERNEL);
+ err_node = kvzalloc_obj(*err_node);
if (!err_node)
return NULL;
@@ -5671,7 +5682,7 @@ int amdgpu_ras_add_critical_region(struct amdgpu_device *adev,
/* Record new critical amdgpu bo */
list_for_each_entry(block, &vres->blocks, link) {
- region = kzalloc(sizeof(*region), GFP_KERNEL);
+ region = kzalloc_obj(*region);
if (!region) {
ret = -ENOMEM;
goto out;