diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index 132d054900b5..d80fe17556da 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -2229,6 +2229,20 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev) debugfs_create_file("amdgpu_benchmark", 0200, root, adev, &amdgpu_benchmark_fops); + /* Debug-only: bitmap of incoming UALink protocol messages to drop. + * Each bit position corresponds to an enum AMDGPU_UALINK_PROTOCOL_MESSAGES + * value. Setting a bit causes exactly one matching incoming packet to be + * dropped, after which the bit auto-clears and traffic resumes. Used to + * exercise the connection reset paths. + * + * Examples (drop one NPA-REQ): + * echo 0x8 > /sys/kernel/debug/dri/0/amdgpu_ualink_drop_msg_bitmap + * (drop one NPA-RSP): + * echo 0x10 > /sys/kernel/debug/dri/0/amdgpu_ualink_drop_msg_bitmap + */ + debugfs_create_ulong("amdgpu_ualink_drop_msg_bitmap", 0600, root, + &adev->ualink.drop_msg_bitmap); + adev->debugfs_vbios_blob.data = adev->bios; adev->debugfs_vbios_blob.size = adev->bios_size; debugfs_create_blob("amdgpu_vbios", 0444, root, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c index 91f124757003..5dcc754f2890 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.c @@ -5395,6 +5395,19 @@ static int amdgpu_ualink_process_irq(struct amdgpu_device *adev, dev_dbg(adev->dev, "Got MSG: remote acc_id %u msg_type %u\n", src_acc_id, msg_type); + /* Debug hook: if the bit corresponding to this msg_type is set in + * drop_msg_bitmap, drop this single packet and clear the bit so that + * any subsequent incoming messages are processed normally. Used to + * exercise the connection reset/recovery paths via debugfs. + */ + if (msg_type < BITS_PER_LONG && + test_and_clear_bit(msg_type, &adev->ualink.drop_msg_bitmap)) { + dev_warn(adev->dev, + "DROP MSG (debugfs): src acc_id %u msg_type %u dw[0-3] 0x%x 0x%x 0x%x 0x%x\n", + src_acc_id, msg_type, dw0, dw1, dw2, dw3); + return handled; + } + switch (msg_type) { case AMDGPU_UALINK_HELLO_MSG: receiver_acc_id = (dw0 >> AMDGPU_UALINK_HELLO_MSG_RECV_ACCID_SHIFT) & diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h index fa116ef44cb5..d4d4ca0199dc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ualink.h @@ -342,6 +342,22 @@ struct amdgpu_ualink_mgr { /* Sequence number to track the need for TLB flushes */ atomic64_t last_flushed_tlb_seq; + + /* Debug-only: bitmap of incoming UALink protocol messages to drop. + * + * Each bit position corresponds to a value from + * enum AMDGPU_UALINK_PROTOCOL_MESSAGES: + * BIT(AMDGPU_UALINK_NPA_REQ_MSG) drops one incoming NPA-REQ. + * BIT(AMDGPU_UALINK_NPA_RSP_MSG) drops one incoming NPA-RSP. + * + * On reception of a message whose corresponding bit is set, the bit + * is atomically cleared and the message is silently dropped. This + * means at most one packet per set bit is dropped; any further + * incoming packets of the same type are processed normally. This is + * intended to exercise the connection reset / recovery paths from a + * debugfs handle. + */ + unsigned long drop_msg_bitmap; }; int amdgpu_ualink_init_interrupt(struct amdgpu_device *adev);