Merge tag 'amd-drm-next-7.1-2026-03-12' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-next-7.1-2026-03-12:

amdgpu:
- SMU13 fix
- SMU14 fix
- Fixes for bring up hw testing
- Kerneldoc fix
- GC12 idle power fix for compute workloads
- DCCG fixes
- UserQ fixes
- Move test for fbdev object to a generic helper
- GC 12.1 updates
- Use struct drm_edid in non-DC code
- Include IP discovery data in devcoredump
- SMU 13.x updates
- Misc cleanups
- DML 2.1 fixes
- Enable NV12/P010 support on primary planes
- Enable color encoding and color range on overlay planes
- DC underflow fixes
- HWSS fast path fixes
- Replay fixes
- DCN 4.2 updates
- Support newer IP discovery tables
- LSDMA 7.1 support
- IH 7.1 fixes
- SoC v1 updates
- GC12.1 updates
- PSP 15 updates
- XGMI fixes
- GPUVM locking fix

amdkfd:
- Fix missing BO unreserve in an error path

radeon:
- Move test for fbdev object to a generic helper

From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patch.msgid.link/20260312184425.3875669-1-alexander.deucher@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie
2026-03-16 16:50:53 +10:00
163 changed files with 3824 additions and 2528 deletions
+1 -1
View File
@@ -86,7 +86,7 @@ amdgpu-y += \
nbio_v7_2.o hdp_v4_0.o hdp_v5_0.o aldebaran_reg_init.o aldebaran.o soc21.o soc24.o \
sienna_cichlid.o smu_v13_0_10.o nbio_v4_3.o hdp_v6_0.o nbio_v7_7.o hdp_v5_2.o lsdma_v6_0.o \
nbio_v7_9.o aqua_vanjaram.o nbio_v7_11.o lsdma_v7_0.o hdp_v7_0.o nbif_v6_3_1.o \
cyan_skillfish_reg_init.o soc_v1_0.o
cyan_skillfish_reg_init.o soc_v1_0.o lsdma_v7_1.o
# add DF block
amdgpu-y += \
+23 -31
View File
@@ -246,10 +246,10 @@ amdgpu_connector_find_encoder(struct drm_connector *connector,
return NULL;
}
static struct edid *
static const struct drm_edid *
amdgpu_connector_get_hardcoded_edid(struct amdgpu_device *adev)
{
return drm_edid_duplicate(drm_edid_raw(adev->mode_info.bios_hardcoded_edid));
return drm_edid_dup(adev->mode_info.bios_hardcoded_edid);
}
static void amdgpu_connector_get_edid(struct drm_connector *connector)
@@ -268,8 +268,8 @@ static void amdgpu_connector_get_edid(struct drm_connector *connector)
if ((amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=
ENCODER_OBJECT_ID_NONE) &&
amdgpu_connector->ddc_bus->has_aux) {
amdgpu_connector->edid = drm_get_edid(connector,
&amdgpu_connector->ddc_bus->aux.ddc);
amdgpu_connector->edid = drm_edid_read_ddc(connector,
&amdgpu_connector->ddc_bus->aux.ddc);
} else if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
(connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
struct amdgpu_connector_atom_dig *dig = amdgpu_connector->con_priv;
@@ -277,14 +277,14 @@ static void amdgpu_connector_get_edid(struct drm_connector *connector)
if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
amdgpu_connector->ddc_bus->has_aux)
amdgpu_connector->edid = drm_get_edid(connector,
&amdgpu_connector->ddc_bus->aux.ddc);
amdgpu_connector->edid = drm_edid_read_ddc(connector,
&amdgpu_connector->ddc_bus->aux.ddc);
else if (amdgpu_connector->ddc_bus)
amdgpu_connector->edid = drm_get_edid(connector,
&amdgpu_connector->ddc_bus->adapter);
amdgpu_connector->edid = drm_edid_read_ddc(connector,
&amdgpu_connector->ddc_bus->adapter);
} else if (amdgpu_connector->ddc_bus) {
amdgpu_connector->edid = drm_get_edid(connector,
&amdgpu_connector->ddc_bus->adapter);
amdgpu_connector->edid = drm_edid_read_ddc(connector,
&amdgpu_connector->ddc_bus->adapter);
}
if (!amdgpu_connector->edid) {
@@ -292,30 +292,22 @@ static void amdgpu_connector_get_edid(struct drm_connector *connector)
if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ||
(connector->connector_type == DRM_MODE_CONNECTOR_eDP))) {
amdgpu_connector->edid = amdgpu_connector_get_hardcoded_edid(adev);
drm_connector_update_edid_property(connector, amdgpu_connector->edid);
drm_edid_connector_update(connector, amdgpu_connector->edid);
}
}
}
static void amdgpu_connector_free_edid(struct drm_connector *connector)
{
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
kfree(amdgpu_connector->edid);
amdgpu_connector->edid = NULL;
}
static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)
{
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
int ret;
if (amdgpu_connector->edid) {
drm_connector_update_edid_property(connector, amdgpu_connector->edid);
ret = drm_add_edid_modes(connector, amdgpu_connector->edid);
drm_edid_connector_update(connector, amdgpu_connector->edid);
ret = drm_edid_connector_add_modes(connector);
return ret;
}
drm_connector_update_edid_property(connector, NULL);
drm_edid_connector_update(connector, NULL);
return 0;
}
@@ -754,7 +746,7 @@ static void amdgpu_connector_destroy(struct drm_connector *connector)
{
struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
amdgpu_connector_free_edid(connector);
drm_edid_free(amdgpu_connector->edid);
kfree(amdgpu_connector->con_priv);
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
@@ -873,7 +865,7 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
dret = amdgpu_display_ddc_probe(amdgpu_connector, false);
if (dret) {
amdgpu_connector->detected_by_load = false;
amdgpu_connector_free_edid(connector);
drm_edid_free(amdgpu_connector->edid);
amdgpu_connector_get_edid(connector);
if (!amdgpu_connector->edid) {
@@ -883,13 +875,13 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
ret = connector_status_connected;
} else {
amdgpu_connector->use_digital =
!!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
drm_edid_is_digital(amdgpu_connector->edid);
/* some oems have boards with separate digital and analog connectors
* with a shared ddc line (often vga + hdmi)
*/
if (amdgpu_connector->use_digital && amdgpu_connector->shared_ddc) {
amdgpu_connector_free_edid(connector);
drm_edid_free(amdgpu_connector->edid);
ret = connector_status_disconnected;
} else {
ret = connector_status_connected;
@@ -984,7 +976,7 @@ static void amdgpu_connector_shared_ddc(enum drm_connector_status *status,
/* hpd is our only option in this case */
if (!amdgpu_display_hpd_sense(adev,
amdgpu_connector->hpd.hpd)) {
amdgpu_connector_free_edid(connector);
drm_edid_free(amdgpu_connector->edid);
*status = connector_status_disconnected;
}
}
@@ -1053,7 +1045,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
}
if (dret) {
amdgpu_connector->detected_by_load = false;
amdgpu_connector_free_edid(connector);
drm_edid_free(amdgpu_connector->edid);
amdgpu_connector_get_edid(connector);
if (!amdgpu_connector->edid) {
@@ -1063,13 +1055,13 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
broken_edid = true; /* defer use_digital to later */
} else {
amdgpu_connector->use_digital =
!!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
drm_edid_is_digital(amdgpu_connector->edid);
/* some oems have boards with separate digital and analog connectors
* with a shared ddc line (often vga + hdmi)
*/
if ((!amdgpu_connector->use_digital) && amdgpu_connector->shared_ddc) {
amdgpu_connector_free_edid(connector);
drm_edid_free(amdgpu_connector->edid);
ret = connector_status_disconnected;
} else {
ret = connector_status_connected;
@@ -1417,7 +1409,7 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
goto out;
}
amdgpu_connector_free_edid(connector);
drm_edid_free(amdgpu_connector->edid);
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
@@ -39,6 +39,7 @@
#include "amdgpu_reset.h"
#include "amdgpu_psp_ta.h"
#include "amdgpu_userq.h"
#if defined(CONFIG_DEBUG_FS)
@@ -2156,6 +2157,53 @@ static const struct file_operations amdgpu_pt_info_fops = {
.release = single_release,
};
static int amdgpu_mqd_info_read(struct seq_file *m, void *unused)
{
struct amdgpu_usermode_queue *queue = m->private;
struct amdgpu_bo *bo;
int r;
if (!queue || !queue->mqd.obj)
return -EINVAL;
bo = amdgpu_bo_ref(queue->mqd.obj);
r = amdgpu_bo_reserve(bo, true);
if (r) {
amdgpu_bo_unref(&bo);
return -EINVAL;
}
seq_printf(m, "queue_type: %d\n", queue->queue_type);
seq_printf(m, "mqd_gpu_address: 0x%llx\n", amdgpu_bo_gpu_offset(queue->mqd.obj));
amdgpu_bo_unreserve(bo);
amdgpu_bo_unref(&bo);
return 0;
}
static int amdgpu_mqd_info_open(struct inode *inode, struct file *file)
{
return single_open(file, amdgpu_mqd_info_read, inode->i_private);
}
static const struct file_operations amdgpu_mqd_info_fops = {
.owner = THIS_MODULE,
.open = amdgpu_mqd_info_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
void amdgpu_debugfs_userq_init(struct drm_file *file, struct amdgpu_usermode_queue *queue, int qid)
{
char queue_name[32];
scnprintf(queue_name, sizeof(queue_name), "queue_%d", qid);
queue->debugfs_queue = debugfs_create_dir(queue_name, file->debugfs_client);
debugfs_create_file("mqd_info", 0444, queue->debugfs_queue, queue, &amdgpu_mqd_info_fops);
}
void amdgpu_debugfs_vm_init(struct drm_file *file)
{
debugfs_create_file("vm_pagetable_info", 0444, file->debugfs_client, file,
@@ -2174,4 +2222,9 @@ int amdgpu_debugfs_regs_init(struct amdgpu_device *adev)
void amdgpu_debugfs_vm_init(struct drm_file *file)
{
}
void amdgpu_debugfs_userq_init(struct drm_file *file,
struct amdgpu_usermode_queue *queue,
int qid)
{
}
#endif
@@ -25,6 +25,7 @@
/*
* Debugfs
*/
struct amdgpu_usermode_queue;
int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
int amdgpu_debugfs_init(struct amdgpu_device *adev);
@@ -34,4 +35,7 @@ void amdgpu_debugfs_firmware_init(struct amdgpu_device *adev);
void amdgpu_debugfs_gem_init(struct amdgpu_device *adev);
void amdgpu_debugfs_mes_event_log_init(struct amdgpu_device *adev);
void amdgpu_debugfs_vm_init(struct drm_file *file);
void amdgpu_debugfs_userq_init(struct drm_file *file,
struct amdgpu_usermode_queue *queue,
int qid);
@@ -261,6 +261,8 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count,
}
}
amdgpu_discovery_dump(coredump->adev, &p);
/* IP firmware information */
drm_printf(&p, "\nIP Firmwares\n");
amdgpu_devcoredump_fw_info(coredump->adev, &p);
+13 -1
View File
@@ -1995,8 +1995,10 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev)
break;
default:
r = amdgpu_discovery_set_ip_blocks(adev);
if (r)
if (r) {
adev->num_ip_blocks = 0;
return r;
}
break;
}
@@ -2550,6 +2552,8 @@ int amdgpu_device_set_cg_state(struct amdgpu_device *adev,
i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
if (!adev->ip_blocks[i].status.late_initialized)
continue;
if (!adev->ip_blocks[i].version)
continue;
/* skip CG for GFX, SDMA on S0ix */
if (adev->in_s0ix &&
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
@@ -2589,6 +2593,8 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev,
i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1;
if (!adev->ip_blocks[i].status.late_initialized)
continue;
if (!adev->ip_blocks[i].version)
continue;
/* skip PG for GFX, SDMA on S0ix */
if (adev->in_s0ix &&
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
@@ -2796,6 +2802,8 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev)
int i, r;
for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_blocks[i].version)
continue;
if (!adev->ip_blocks[i].version->funcs->early_fini)
continue;
@@ -2873,6 +2881,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
if (!adev->ip_blocks[i].status.sw)
continue;
if (!adev->ip_blocks[i].version)
continue;
if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) {
amdgpu_ucode_free_bo(adev);
amdgpu_free_static_csa(&adev->virt.csa_obj);
@@ -2899,6 +2909,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_blocks[i].status.late_initialized)
continue;
if (!adev->ip_blocks[i].version)
continue;
if (adev->ip_blocks[i].version->funcs->late_fini)
adev->ip_blocks[i].version->funcs->late_fini(&adev->ip_blocks[i]);
adev->ip_blocks[i].status.late_initialized = false;
File diff suppressed because it is too large Load Diff
@@ -30,10 +30,12 @@
#define DISCOVERY_TMR_OFFSET (64 << 10)
struct ip_discovery_top;
struct drm_printer;
struct amdgpu_discovery_info {
struct debugfs_blob_wrapper debugfs_blob;
struct ip_discovery_top *ip_top;
uint64_t offset;
uint32_t size;
uint8_t *bin;
bool reserve_tmr;
@@ -47,4 +49,6 @@ int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev,
struct amdgpu_gmc_memrange **ranges,
int *range_cnt, bool refresh);
void amdgpu_discovery_dump(struct amdgpu_device *adev, struct drm_printer *p);
#endif /* __AMDGPU_DISCOVERY__ */
+3 -18
View File
@@ -1738,21 +1738,6 @@ bool amdgpu_crtc_get_scanout_position(struct drm_crtc *crtc,
stime, etime, mode);
}
static bool
amdgpu_display_robj_is_fb(struct amdgpu_device *adev, struct amdgpu_bo *robj)
{
struct drm_device *dev = adev_to_drm(adev);
struct drm_fb_helper *fb_helper = dev->fb_helper;
if (!fb_helper || !fb_helper->buffer)
return false;
if (gem_to_amdgpu_bo(fb_helper->buffer->gem) != robj)
return false;
return true;
}
int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
{
struct drm_device *dev = adev_to_drm(adev);
@@ -1775,7 +1760,6 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
struct drm_framebuffer *fb = crtc->primary->fb;
struct amdgpu_bo *robj;
if (amdgpu_crtc->cursor_bo && !adev->enable_virtual_display) {
struct amdgpu_bo *aobj = gem_to_amdgpu_bo(amdgpu_crtc->cursor_bo);
@@ -1790,8 +1774,9 @@ int amdgpu_display_suspend_helper(struct amdgpu_device *adev)
if (!fb || !fb->obj[0])
continue;
robj = gem_to_amdgpu_bo(fb->obj[0]);
if (!amdgpu_display_robj_is_fb(adev, robj)) {
if (!drm_fb_helper_gem_is_fb(dev->fb_helper, fb->obj[0])) {
struct amdgpu_bo *robj = gem_to_amdgpu_bo(fb->obj[0]);
r = amdgpu_bo_reserve(robj, true);
if (r == 0) {
amdgpu_bo_unpin(robj);
+4
View File
@@ -94,6 +94,10 @@ enum amdgpu_memory_partition {
#define AMDGPU_GMC9_FAULT_SOURCE_DATA_WRITE 0x20
#define AMDGPU_GMC9_FAULT_SOURCE_DATA_EXE 0x10
#define AMDGPU_GMC121_FAULT_SOURCE_DATA_READ 0x400000
#define AMDGPU_GMC121_FAULT_SOURCE_DATA_WRITE 0x200000
#define AMDGPU_GMC121_FAULT_SOURCE_DATA_EXE 0x100000
/*
* GMC page fault information
*/
+1 -1
View File
@@ -83,7 +83,7 @@ void amdgpu_driver_unload_kms(struct drm_device *dev)
{
struct amdgpu_device *adev = drm_to_adev(dev);
if (adev == NULL)
if (adev == NULL || !adev->num_ip_blocks)
return;
amdgpu_unregister_gpu_instance(adev);
+3 -3
View File
@@ -159,9 +159,9 @@ struct amdgpu_mes {
int hung_queue_db_array_size;
int hung_queue_hqd_info_offset;
struct amdgpu_bo *hung_queue_db_array_gpu_obj[AMDGPU_MAX_MES_PIPES];
uint64_t hung_queue_db_array_gpu_addr[AMDGPU_MAX_MES_PIPES];
void *hung_queue_db_array_cpu_addr[AMDGPU_MAX_MES_PIPES];
struct amdgpu_bo *hung_queue_db_array_gpu_obj[AMDGPU_MAX_MES_INST_PIPES];
uint64_t hung_queue_db_array_gpu_addr[AMDGPU_MAX_MES_INST_PIPES];
void *hung_queue_db_array_cpu_addr[AMDGPU_MAX_MES_INST_PIPES];
/* cooperative dispatch */
bool enable_coop_mode;
+9 -9
View File
@@ -368,15 +368,15 @@ struct amdgpu_mode_info {
struct drm_property *plane_ctm_property;
/**
* @shaper_lut_property: Plane property to set pre-blending shaper LUT
* that converts color content before 3D LUT. If
* plane_shaper_tf_property != Identity TF, AMD color module will
* @plane_shaper_lut_property: Plane property to set pre-blending
* shaper LUT that converts color content before 3D LUT.
* If plane_shaper_tf_property != Identity TF, AMD color module will
* combine the user LUT values with pre-defined TF into the LUT
* parameters to be programmed.
*/
struct drm_property *plane_shaper_lut_property;
/**
* @shaper_lut_size_property: Plane property for the size of
* @plane_shaper_lut_size_property: Plane property for the size of
* pre-blending shaper LUT as supported by the driver (read-only).
*/
struct drm_property *plane_shaper_lut_size_property;
@@ -400,10 +400,10 @@ struct amdgpu_mode_info {
*/
struct drm_property *plane_lut3d_property;
/**
* @plane_degamma_lut_size_property: Plane property to define the max
* size of 3D LUT as supported by the driver (read-only). The max size
* is the max size of one dimension and, therefore, the max number of
* entries for 3D LUT array is the 3D LUT size cubed;
* @plane_lut3d_size_property: Plane property to define the max size
* of 3D LUT as supported by the driver (read-only). The max size is
* the max size of one dimension and, therefore, the max number of
* entries for 3D LUT array is the 3D LUT size cubed.
*/
struct drm_property *plane_lut3d_size_property;
/**
@@ -624,7 +624,7 @@ struct amdgpu_connector {
bool use_digital;
/* we need to mind the EDID between detect
and get modes due to analog/digital/tvencoder */
struct edid *edid;
const struct drm_edid *edid;
void *con_priv;
bool dac_load_detect;
bool detected_by_load; /* if the connection status was determined by load */
+7
View File
@@ -3096,6 +3096,13 @@ static int psp_load_non_psp_fw(struct psp_context *psp)
*/
continue;
/* IMU ucode is part of IFWI and MP0 15.0.8 would load it */
if (amdgpu_ip_version(adev, MP0_HWIP, 0) ==
IP_VERSION(15, 0, 8) &&
(ucode->ucode_id == AMDGPU_UCODE_ID_IMU_I ||
ucode->ucode_id == AMDGPU_UCODE_ID_IMU_D))
continue;
psp_print_fw_hdr(psp, ucode);
ret = psp_execute_ip_fw_load(psp, ucode);
+8 -8
View File
@@ -291,22 +291,22 @@ void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr)
break;
case 5:
/* rlc_hdr v2_5 */
DRM_INFO("rlc_iram_ucode_size_bytes: %u\n",
DRM_DEBUG("rlc_iram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_size_bytes));
DRM_INFO("rlc_iram_ucode_offset_bytes: %u\n",
DRM_DEBUG("rlc_iram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_iram_ucode_offset_bytes));
DRM_INFO("rlc_dram_ucode_size_bytes: %u\n",
DRM_DEBUG("rlc_dram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_size_bytes));
DRM_INFO("rlc_dram_ucode_offset_bytes: %u\n",
DRM_DEBUG("rlc_dram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->v2_2.rlc_dram_ucode_offset_bytes));
/* rlc_hdr v2_5 */
DRM_INFO("rlc_1_iram_ucode_size_bytes: %u\n",
DRM_DEBUG("rlc_1_iram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_size_bytes));
DRM_INFO("rlc_1_iram_ucode_offset_bytes: %u\n",
DRM_DEBUG("rlc_1_iram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->rlc_1_iram_ucode_offset_bytes));
DRM_INFO("rlc_1_dram_ucode_size_bytes: %u\n",
DRM_DEBUG("rlc_1_dram_ucode_size_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_size_bytes));
DRM_INFO("rlc_1_dram_ucode_offset_bytes: %u\n",
DRM_DEBUG("rlc_1_dram_ucode_offset_bytes: %u\n",
le32_to_cpu(rlc_hdr_v2_5->rlc_1_dram_ucode_offset_bytes));
break;
default:
+43 -92
View File
@@ -709,46 +709,6 @@ static int amdgpu_userq_priority_permit(struct drm_file *filp,
return -EACCES;
}
#if defined(CONFIG_DEBUG_FS)
static int amdgpu_mqd_info_read(struct seq_file *m, void *unused)
{
struct amdgpu_usermode_queue *queue = m->private;
struct amdgpu_bo *bo;
int r;
if (!queue || !queue->mqd.obj)
return -EINVAL;
bo = amdgpu_bo_ref(queue->mqd.obj);
r = amdgpu_bo_reserve(bo, true);
if (r) {
amdgpu_bo_unref(&bo);
return -EINVAL;
}
seq_printf(m, "queue_type: %d\n", queue->queue_type);
seq_printf(m, "mqd_gpu_address: 0x%llx\n", amdgpu_bo_gpu_offset(queue->mqd.obj));
amdgpu_bo_unreserve(bo);
amdgpu_bo_unref(&bo);
return 0;
}
static int amdgpu_mqd_info_open(struct inode *inode, struct file *file)
{
return single_open(file, amdgpu_mqd_info_read, inode->i_private);
}
static const struct file_operations amdgpu_mqd_info_fops = {
.owner = THIS_MODULE,
.open = amdgpu_mqd_info_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#endif
static int
amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
{
@@ -758,7 +718,6 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
const struct amdgpu_userq_funcs *uq_funcs;
struct amdgpu_usermode_queue *queue;
struct amdgpu_db_info db_info;
char *queue_name;
bool skip_map_queue;
u32 qid;
uint64_t index;
@@ -819,17 +778,15 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
amdgpu_userq_input_va_validate(adev, queue, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) ||
amdgpu_userq_input_va_validate(adev, queue, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) {
r = -EINVAL;
kfree(queue);
goto unlock;
goto free_queue;
}
/* Convert relative doorbell offset into absolute doorbell index */
index = amdgpu_userq_get_doorbell_index(uq_mgr, &db_info, filp);
if (index == (uint64_t)-EINVAL) {
drm_file_err(uq_mgr->file, "Failed to get doorbell for queue\n");
kfree(queue);
r = -EINVAL;
goto unlock;
goto free_queue;
}
queue->doorbell_index = index;
@@ -837,42 +794,15 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
r = amdgpu_userq_fence_driver_alloc(adev, queue);
if (r) {
drm_file_err(uq_mgr->file, "Failed to alloc fence driver\n");
goto unlock;
goto free_queue;
}
r = uq_funcs->mqd_create(queue, &args->in);
if (r) {
drm_file_err(uq_mgr->file, "Failed to create Queue\n");
amdgpu_userq_fence_driver_free(queue);
kfree(queue);
goto unlock;
goto clean_fence_driver;
}
/* drop this refcount during queue destroy */
kref_init(&queue->refcount);
/* Wait for mode-1 reset to complete */
down_read(&adev->reset_domain->sem);
r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL));
if (r) {
kfree(queue);
up_read(&adev->reset_domain->sem);
goto unlock;
}
r = xa_alloc(&uq_mgr->userq_xa, &qid, queue,
XA_LIMIT(1, AMDGPU_MAX_USERQ_COUNT), GFP_KERNEL);
if (r) {
drm_file_err(uq_mgr->file, "Failed to allocate a queue id\n");
amdgpu_userq_fence_driver_free(queue);
uq_funcs->mqd_destroy(queue);
kfree(queue);
r = -ENOMEM;
up_read(&adev->reset_domain->sem);
goto unlock;
}
up_read(&adev->reset_domain->sem);
/* don't map the queue if scheduling is halted */
if (adev->userq_halt_for_enforce_isolation &&
((queue->queue_type == AMDGPU_HW_IP_GFX) ||
@@ -884,31 +814,52 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
r = amdgpu_userq_map_helper(queue);
if (r) {
drm_file_err(uq_mgr->file, "Failed to map Queue\n");
xa_erase(&uq_mgr->userq_xa, qid);
amdgpu_userq_fence_driver_free(queue);
uq_funcs->mqd_destroy(queue);
kfree(queue);
goto unlock;
down_read(&adev->reset_domain->sem);
goto clean_mqd;
}
}
queue_name = kasprintf(GFP_KERNEL, "queue-%d", qid);
if (!queue_name) {
/* drop this refcount during queue destroy */
kref_init(&queue->refcount);
/* Wait for mode-1 reset to complete */
down_read(&adev->reset_domain->sem);
r = xa_alloc(&uq_mgr->userq_xa, &qid, queue,
XA_LIMIT(1, AMDGPU_MAX_USERQ_COUNT), GFP_KERNEL);
if (r) {
if (!skip_map_queue)
amdgpu_userq_unmap_helper(queue);
r = -ENOMEM;
goto unlock;
goto clean_mqd;
}
#if defined(CONFIG_DEBUG_FS)
/* Queue dentry per client to hold MQD information */
queue->debugfs_queue = debugfs_create_dir(queue_name, filp->debugfs_client);
debugfs_create_file("mqd_info", 0444, queue->debugfs_queue, queue, &amdgpu_mqd_info_fops);
#endif
r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL));
if (r) {
xa_erase(&uq_mgr->userq_xa, qid);
if (!skip_map_queue)
amdgpu_userq_unmap_helper(queue);
goto clean_mqd;
}
up_read(&adev->reset_domain->sem);
amdgpu_debugfs_userq_init(filp, queue, qid);
amdgpu_userq_init_hang_detect_work(queue);
kfree(queue_name);
args->out.queue_id = qid;
atomic_inc(&uq_mgr->userq_count[queue->queue_type]);
mutex_unlock(&uq_mgr->userq_mutex);
return 0;
clean_mqd:
uq_funcs->mqd_destroy(queue);
up_read(&adev->reset_domain->sem);
clean_fence_driver:
amdgpu_userq_fence_driver_free(queue);
free_queue:
kfree(queue);
unlock:
mutex_unlock(&uq_mgr->userq_mutex);
@@ -1089,12 +1040,12 @@ amdgpu_userq_bo_validate(struct amdgpu_device *adev, struct drm_exec *exec,
struct amdgpu_bo *bo;
int ret;
spin_lock(&vm->status_lock);
spin_lock(&vm->invalidated_lock);
while (!list_empty(&vm->invalidated)) {
bo_va = list_first_entry(&vm->invalidated,
struct amdgpu_bo_va,
base.vm_status);
spin_unlock(&vm->status_lock);
spin_unlock(&vm->invalidated_lock);
bo = bo_va->base.bo;
ret = drm_exec_prepare_obj(exec, &bo->tbo.base, 2);
@@ -1111,9 +1062,9 @@ amdgpu_userq_bo_validate(struct amdgpu_device *adev, struct drm_exec *exec,
if (ret)
return ret;
spin_lock(&vm->status_lock);
spin_lock(&vm->invalidated_lock);
}
spin_unlock(&vm->status_lock);
spin_unlock(&vm->invalidated_lock);
return 0;
}
+4
View File
@@ -162,6 +162,7 @@ enum AMDGIM_FEATURE_FLAG {
AMDGIM_FEATURE_RAS_TELEMETRY = (1 << 10),
AMDGIM_FEATURE_RAS_CPER = (1 << 11),
AMDGIM_FEATURE_XGMI_TA_EXT_PEER_LINK = (1 << 12),
AMDGIM_FEATURE_XGMI_CONNECTED_TO_CPU = (1 << 13),
};
enum AMDGIM_REG_ACCESS_FLAG {
@@ -412,6 +413,9 @@ struct amdgpu_video_codec_info;
#define amdgpu_sriov_xgmi_ta_ext_peer_link_en(adev) \
((adev)->virt.gim_feature & AMDGIM_FEATURE_XGMI_TA_EXT_PEER_LINK)
#define amdgpu_sriov_xgmi_connected_to_cpu(adev) \
((adev)->virt.gim_feature & AMDGIM_FEATURE_XGMI_CONNECTED_TO_CPU)
static inline bool is_virtual_machine(void)
{
#if defined(CONFIG_X86)
+55 -91
View File
@@ -153,12 +153,10 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
vm_bo->moved = true;
amdgpu_vm_assert_locked(vm);
spin_lock(&vm_bo->vm->status_lock);
if (bo->tbo.type == ttm_bo_type_kernel)
list_move(&vm_bo->vm_status, &vm->evicted);
else
list_move_tail(&vm_bo->vm_status, &vm->evicted);
spin_unlock(&vm_bo->vm->status_lock);
}
/**
* amdgpu_vm_bo_moved - vm_bo is moved
@@ -171,9 +169,7 @@ static void amdgpu_vm_bo_evicted(struct amdgpu_vm_bo_base *vm_bo)
static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
{
amdgpu_vm_assert_locked(vm_bo->vm);
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->moved);
spin_unlock(&vm_bo->vm->status_lock);
}
/**
@@ -187,9 +183,7 @@ static void amdgpu_vm_bo_moved(struct amdgpu_vm_bo_base *vm_bo)
static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
{
amdgpu_vm_assert_locked(vm_bo->vm);
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->idle);
spin_unlock(&vm_bo->vm->status_lock);
vm_bo->moved = false;
}
@@ -203,9 +197,9 @@ static void amdgpu_vm_bo_idle(struct amdgpu_vm_bo_base *vm_bo)
*/
static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
{
spin_lock(&vm_bo->vm->status_lock);
spin_lock(&vm_bo->vm->invalidated_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->invalidated);
spin_unlock(&vm_bo->vm->status_lock);
spin_unlock(&vm_bo->vm->invalidated_lock);
}
/**
@@ -218,10 +212,9 @@ static void amdgpu_vm_bo_invalidated(struct amdgpu_vm_bo_base *vm_bo)
*/
static void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo)
{
amdgpu_vm_assert_locked(vm_bo->vm);
vm_bo->moved = true;
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->evicted_user);
spin_unlock(&vm_bo->vm->status_lock);
}
/**
@@ -235,13 +228,10 @@ static void amdgpu_vm_bo_evicted_user(struct amdgpu_vm_bo_base *vm_bo)
static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
{
amdgpu_vm_assert_locked(vm_bo->vm);
if (vm_bo->bo->parent) {
spin_lock(&vm_bo->vm->status_lock);
if (vm_bo->bo->parent)
list_move(&vm_bo->vm_status, &vm_bo->vm->relocated);
spin_unlock(&vm_bo->vm->status_lock);
} else {
else
amdgpu_vm_bo_idle(vm_bo);
}
}
/**
@@ -255,9 +245,7 @@ static void amdgpu_vm_bo_relocated(struct amdgpu_vm_bo_base *vm_bo)
static void amdgpu_vm_bo_done(struct amdgpu_vm_bo_base *vm_bo)
{
amdgpu_vm_assert_locked(vm_bo->vm);
spin_lock(&vm_bo->vm->status_lock);
list_move(&vm_bo->vm_status, &vm_bo->vm->done);
spin_unlock(&vm_bo->vm->status_lock);
}
/**
@@ -271,13 +259,13 @@ static void amdgpu_vm_bo_reset_state_machine(struct amdgpu_vm *vm)
{
struct amdgpu_vm_bo_base *vm_bo, *tmp;
amdgpu_vm_assert_locked(vm);
spin_lock(&vm->status_lock);
spin_lock(&vm->invalidated_lock);
list_splice_init(&vm->done, &vm->invalidated);
list_for_each_entry(vm_bo, &vm->invalidated, vm_status)
vm_bo->moved = true;
spin_unlock(&vm->invalidated_lock);
amdgpu_vm_assert_locked(vm);
list_for_each_entry_safe(vm_bo, tmp, &vm->idle, vm_status) {
struct amdgpu_bo *bo = vm_bo->bo;
@@ -287,14 +275,13 @@ static void amdgpu_vm_bo_reset_state_machine(struct amdgpu_vm *vm)
else if (bo->parent)
list_move(&vm_bo->vm_status, &vm_bo->vm->relocated);
}
spin_unlock(&vm->status_lock);
}
/**
* amdgpu_vm_update_shared - helper to update shared memory stat
* @base: base structure for tracking BO usage in a VM
*
* Takes the vm status_lock and updates the shared memory stat. If the basic
* Takes the vm stats_lock and updates the shared memory stat. If the basic
* stat changed (e.g. buffer was moved) amdgpu_vm_update_stats need to be called
* as well.
*/
@@ -307,7 +294,7 @@ static void amdgpu_vm_update_shared(struct amdgpu_vm_bo_base *base)
bool shared;
dma_resv_assert_held(bo->tbo.base.resv);
spin_lock(&vm->status_lock);
spin_lock(&vm->stats_lock);
shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base);
if (base->shared != shared) {
base->shared = shared;
@@ -319,7 +306,7 @@ static void amdgpu_vm_update_shared(struct amdgpu_vm_bo_base *base)
vm->stats[bo_memtype].drm.private += size;
}
}
spin_unlock(&vm->status_lock);
spin_unlock(&vm->stats_lock);
}
/**
@@ -344,11 +331,11 @@ void amdgpu_vm_bo_update_shared(struct amdgpu_bo *bo)
* be bo->tbo.resource
* @sign: if we should add (+1) or subtract (-1) from the stat
*
* Caller need to have the vm status_lock held. Useful for when multiple update
* Caller need to have the vm stats_lock held. Useful for when multiple update
* need to happen at the same time.
*/
static void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base,
struct ttm_resource *res, int sign)
struct ttm_resource *res, int sign)
{
struct amdgpu_vm *vm = base->vm;
struct amdgpu_bo *bo = base->bo;
@@ -372,7 +359,8 @@ static void amdgpu_vm_update_stats_locked(struct amdgpu_vm_bo_base *base,
*/
if (bo->flags & AMDGPU_GEM_CREATE_DISCARDABLE)
vm->stats[res_memtype].drm.purgeable += size;
if (!(bo->preferred_domains & amdgpu_mem_type_to_domain(res_memtype)))
if (!(bo->preferred_domains &
amdgpu_mem_type_to_domain(res_memtype)))
vm->stats[bo_memtype].evicted += size;
}
}
@@ -391,9 +379,9 @@ void amdgpu_vm_update_stats(struct amdgpu_vm_bo_base *base,
{
struct amdgpu_vm *vm = base->vm;
spin_lock(&vm->status_lock);
spin_lock(&vm->stats_lock);
amdgpu_vm_update_stats_locked(base, res, sign);
spin_unlock(&vm->status_lock);
spin_unlock(&vm->stats_lock);
}
/**
@@ -419,10 +407,10 @@ void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
base->next = bo->vm_bo;
bo->vm_bo = base;
spin_lock(&vm->status_lock);
spin_lock(&vm->stats_lock);
base->shared = drm_gem_object_is_shared_for_memory_stats(&bo->tbo.base);
amdgpu_vm_update_stats_locked(base, bo->tbo.resource, +1);
spin_unlock(&vm->status_lock);
spin_unlock(&vm->stats_lock);
if (!amdgpu_vm_is_bo_always_valid(vm, bo))
return;
@@ -481,25 +469,25 @@ int amdgpu_vm_lock_done_list(struct amdgpu_vm *vm, struct drm_exec *exec,
int ret;
/* We can only trust prev->next while holding the lock */
spin_lock(&vm->status_lock);
spin_lock(&vm->invalidated_lock);
while (!list_is_head(prev->next, &vm->done)) {
bo_va = list_entry(prev->next, typeof(*bo_va), base.vm_status);
bo = bo_va->base.bo;
if (bo) {
amdgpu_bo_ref(bo);
spin_unlock(&vm->status_lock);
spin_unlock(&vm->invalidated_lock);
ret = drm_exec_prepare_obj(exec, &bo->tbo.base, 1);
amdgpu_bo_unref(&bo);
if (unlikely(ret))
return ret;
spin_lock(&vm->status_lock);
spin_lock(&vm->invalidated_lock);
}
prev = prev->next;
}
spin_unlock(&vm->status_lock);
spin_unlock(&vm->invalidated_lock);
return 0;
}
@@ -595,7 +583,7 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
void *param)
{
uint64_t new_vm_generation = amdgpu_vm_generation(adev, vm);
struct amdgpu_vm_bo_base *bo_base;
struct amdgpu_vm_bo_base *bo_base, *tmp;
struct amdgpu_bo *bo;
int r;
@@ -608,13 +596,7 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
return r;
}
spin_lock(&vm->status_lock);
while (!list_empty(&vm->evicted)) {
bo_base = list_first_entry(&vm->evicted,
struct amdgpu_vm_bo_base,
vm_status);
spin_unlock(&vm->status_lock);
list_for_each_entry_safe(bo_base, tmp, &vm->evicted, vm_status) {
bo = bo_base->bo;
r = validate(param, bo);
@@ -627,26 +609,21 @@ int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
vm->update_funcs->map_table(to_amdgpu_bo_vm(bo));
amdgpu_vm_bo_relocated(bo_base);
}
spin_lock(&vm->status_lock);
}
while (ticket && !list_empty(&vm->evicted_user)) {
bo_base = list_first_entry(&vm->evicted_user,
struct amdgpu_vm_bo_base,
vm_status);
spin_unlock(&vm->status_lock);
bo = bo_base->bo;
dma_resv_assert_held(bo->tbo.base.resv);
if (ticket) {
list_for_each_entry_safe(bo_base, tmp, &vm->evicted_user,
vm_status) {
bo = bo_base->bo;
dma_resv_assert_held(bo->tbo.base.resv);
r = validate(param, bo);
if (r)
return r;
r = validate(param, bo);
if (r)
return r;
amdgpu_vm_bo_invalidated(bo_base);
spin_lock(&vm->status_lock);
amdgpu_vm_bo_invalidated(bo_base);
}
}
spin_unlock(&vm->status_lock);
amdgpu_vm_eviction_lock(vm);
vm->evicting = false;
@@ -675,9 +652,7 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
ret = !vm->evicting;
amdgpu_vm_eviction_unlock(vm);
spin_lock(&vm->status_lock);
ret &= list_empty(&vm->evicted);
spin_unlock(&vm->status_lock);
spin_lock(&vm->immediate.lock);
ret &= !vm->immediate.stopped;
@@ -971,18 +946,13 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
struct amdgpu_vm *vm, bool immediate)
{
struct amdgpu_vm_update_params params;
struct amdgpu_vm_bo_base *entry;
struct amdgpu_vm_bo_base *entry, *tmp;
bool flush_tlb_needed = false;
LIST_HEAD(relocated);
int r, idx;
amdgpu_vm_assert_locked(vm);
spin_lock(&vm->status_lock);
list_splice_init(&vm->relocated, &relocated);
spin_unlock(&vm->status_lock);
if (list_empty(&relocated))
if (list_empty(&vm->relocated))
return 0;
if (!drm_dev_enter(adev_to_drm(adev), &idx))
@@ -998,7 +968,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
if (r)
goto error;
list_for_each_entry(entry, &relocated, vm_status) {
list_for_each_entry(entry, &vm->relocated, vm_status) {
/* vm_flush_needed after updating moved PDEs */
flush_tlb_needed |= entry->moved;
@@ -1014,9 +984,7 @@ int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
if (flush_tlb_needed)
atomic64_inc(&vm->tlb_seq);
while (!list_empty(&relocated)) {
entry = list_first_entry(&relocated, struct amdgpu_vm_bo_base,
vm_status);
list_for_each_entry_safe(entry, tmp, &vm->relocated, vm_status) {
amdgpu_vm_bo_idle(entry);
}
@@ -1243,9 +1211,9 @@ error_free:
void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM])
{
spin_lock(&vm->status_lock);
spin_lock(&vm->stats_lock);
memcpy(stats, vm->stats, sizeof(*stats) * __AMDGPU_PL_NUM);
spin_unlock(&vm->status_lock);
spin_unlock(&vm->stats_lock);
}
/**
@@ -1612,29 +1580,24 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
struct amdgpu_vm *vm,
struct ww_acquire_ctx *ticket)
{
struct amdgpu_bo_va *bo_va;
struct amdgpu_bo_va *bo_va, *tmp;
struct dma_resv *resv;
bool clear, unlock;
int r;
spin_lock(&vm->status_lock);
while (!list_empty(&vm->moved)) {
bo_va = list_first_entry(&vm->moved, struct amdgpu_bo_va,
base.vm_status);
spin_unlock(&vm->status_lock);
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) {
/* Per VM BOs never need to bo cleared in the page tables */
r = amdgpu_vm_bo_update(adev, bo_va, false);
if (r)
return r;
spin_lock(&vm->status_lock);
}
spin_lock(&vm->invalidated_lock);
while (!list_empty(&vm->invalidated)) {
bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va,
base.vm_status);
resv = bo_va->base.bo->tbo.base.resv;
spin_unlock(&vm->status_lock);
spin_unlock(&vm->invalidated_lock);
/* Try to reserve the BO to avoid clearing its ptes */
if (!adev->debug_vm && dma_resv_trylock(resv)) {
@@ -1666,9 +1629,9 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
bo_va->base.bo->tbo.resource->mem_type == TTM_PL_SYSTEM))
amdgpu_vm_bo_evicted_user(&bo_va->base);
spin_lock(&vm->status_lock);
spin_lock(&vm->invalidated_lock);
}
spin_unlock(&vm->status_lock);
spin_unlock(&vm->invalidated_lock);
return 0;
}
@@ -2211,9 +2174,9 @@ void amdgpu_vm_bo_del(struct amdgpu_device *adev,
}
}
spin_lock(&vm->status_lock);
spin_lock(&vm->invalidated_lock);
list_del(&bo_va->base.vm_status);
spin_unlock(&vm->status_lock);
spin_unlock(&vm->invalidated_lock);
list_for_each_entry_safe(mapping, next, &bo_va->valids, list) {
list_del(&mapping->list);
@@ -2321,10 +2284,10 @@ void amdgpu_vm_bo_move(struct amdgpu_bo *bo, struct ttm_resource *new_mem,
for (bo_base = bo->vm_bo; bo_base; bo_base = bo_base->next) {
struct amdgpu_vm *vm = bo_base->vm;
spin_lock(&vm->status_lock);
spin_lock(&vm->stats_lock);
amdgpu_vm_update_stats_locked(bo_base, bo->tbo.resource, -1);
amdgpu_vm_update_stats_locked(bo_base, new_mem, +1);
spin_unlock(&vm->status_lock);
spin_unlock(&vm->stats_lock);
}
amdgpu_vm_bo_invalidate(bo, evicted);
@@ -2593,11 +2556,12 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
INIT_LIST_HEAD(&vm->relocated);
INIT_LIST_HEAD(&vm->moved);
INIT_LIST_HEAD(&vm->idle);
spin_lock_init(&vm->invalidated_lock);
INIT_LIST_HEAD(&vm->invalidated);
spin_lock_init(&vm->status_lock);
INIT_LIST_HEAD(&vm->freed);
INIT_LIST_HEAD(&vm->done);
INIT_KFIFO(vm->faults);
spin_lock_init(&vm->stats_lock);
r = amdgpu_vm_init_entities(adev, vm);
if (r)
@@ -3065,7 +3029,6 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
amdgpu_vm_assert_locked(vm);
spin_lock(&vm->status_lock);
seq_puts(m, "\tIdle BOs:\n");
list_for_each_entry_safe(bo_va, tmp, &vm->idle, base.vm_status) {
if (!bo_va->base.bo)
@@ -3103,11 +3066,13 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
id = 0;
seq_puts(m, "\tInvalidated BOs:\n");
spin_lock(&vm->invalidated_lock);
list_for_each_entry_safe(bo_va, tmp, &vm->invalidated, base.vm_status) {
if (!bo_va->base.bo)
continue;
total_invalidated += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
}
spin_unlock(&vm->invalidated_lock);
total_invalidated_objs = id;
id = 0;
@@ -3117,7 +3082,6 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m)
continue;
total_done += amdgpu_bo_print_info(id++, bo_va->base.bo, m);
}
spin_unlock(&vm->status_lock);
total_done_objs = id;
seq_printf(m, "\tTotal idle size: %12lld\tobjs:\t%d\n", total_idle,
+9 -6
View File
@@ -205,11 +205,11 @@ struct amdgpu_vm_bo_base {
/* protected by bo being reserved */
struct amdgpu_vm_bo_base *next;
/* protected by vm status_lock */
/* protected by vm reservation and invalidated_lock */
struct list_head vm_status;
/* if the bo is counted as shared in mem stats
* protected by vm status_lock */
* protected by vm BO being reserved */
bool shared;
/* protected by the BO being reserved */
@@ -345,10 +345,8 @@ struct amdgpu_vm {
bool evicting;
unsigned int saved_flags;
/* Lock to protect vm_bo add/del/move on all lists of vm */
spinlock_t status_lock;
/* Memory statistics for this vm, protected by status_lock */
/* Memory statistics for this vm, protected by stats_lock */
spinlock_t stats_lock;
struct amdgpu_mem_stats stats[__AMDGPU_PL_NUM];
/*
@@ -356,6 +354,8 @@ struct amdgpu_vm {
* PDs, PTs or per VM BOs. The state transits are:
*
* evicted -> relocated (PDs, PTs) or moved (per VM BOs) -> idle
*
* Lists are protected by the root PD dma_resv lock.
*/
/* Per-VM and PT BOs who needs a validation */
@@ -376,7 +376,10 @@ struct amdgpu_vm {
* state transits are:
*
* evicted_user or invalidated -> done
*
* Lists are protected by the invalidated_lock.
*/
spinlock_t invalidated_lock;
/* BOs for user mode queues that need a validation */
struct list_head evicted_user;
@@ -544,9 +544,7 @@ static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry)
entry->bo->vm_bo = NULL;
ttm_bo_set_bulk_move(&entry->bo->tbo, NULL);
spin_lock(&entry->vm->status_lock);
list_del(&entry->vm_status);
spin_unlock(&entry->vm->status_lock);
amdgpu_bo_unref(&entry->bo);
}
@@ -590,7 +588,6 @@ static void amdgpu_vm_pt_add_list(struct amdgpu_vm_update_params *params,
struct amdgpu_vm_pt_cursor seek;
struct amdgpu_vm_bo_base *entry;
spin_lock(&params->vm->status_lock);
for_each_amdgpu_vm_pt_dfs_safe(params->adev, params->vm, cursor, seek, entry) {
if (entry && entry->bo)
list_move(&entry->vm_status, &params->tlb_flush_waitlist);
@@ -598,7 +595,6 @@ static void amdgpu_vm_pt_add_list(struct amdgpu_vm_update_params *params,
/* enter start node now */
list_move(&cursor->entry->vm_status, &params->tlb_flush_waitlist);
spin_unlock(&params->vm->status_lock);
}
/**

Some files were not shown because too many files have changed in this diff Show More