From: Iouri Tarassov <[email protected]> When D3DKMT requests are sent too quickly, the VM bus ring buffer could be full when a message is submitted. The change adds sleep and re-try count to handle this condition.
Signed-off-by: Iouri Tarassov <[email protected]> [kms: forward port to 6.6 from 6.1. No code changes made.] Signed-off-by: Kelsey Steele <[email protected]> --- drivers/hv/dxgkrnl/dxgvmbus.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/hv/dxgkrnl/dxgvmbus.c b/drivers/hv/dxgkrnl/dxgvmbus.c index 67f55f4bf41d..467e7707c8c7 100644 --- a/drivers/hv/dxgkrnl/dxgvmbus.c +++ b/drivers/hv/dxgkrnl/dxgvmbus.c @@ -420,6 +420,7 @@ int dxgvmb_send_sync_msg(struct dxgvmbuschannel *channel, struct dxgvmbuspacket *packet = NULL; struct dxgkvmb_command_vm_to_host *cmd1; struct dxgkvmb_command_vgpu_to_host *cmd2; + int try_count = 0; if (cmd_size > DXG_MAX_VM_BUS_PACKET_SIZE || result_size > DXG_MAX_VM_BUS_PACKET_SIZE) { @@ -453,9 +454,19 @@ int dxgvmb_send_sync_msg(struct dxgvmbuschannel *channel, list_add_tail(&packet->packet_list_entry, &channel->packet_list_head); spin_unlock_irq(&channel->packet_list_mutex); - ret = vmbus_sendpacket(channel->channel, command, cmd_size, - packet->request_id, VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + do { + ret = vmbus_sendpacket(channel->channel, command, cmd_size, + packet->request_id, VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + /* + * -EAGAIN is returned when the VM bus ring buffer if full. + * Wait 2ms to allow the host to process messages and try again. + */ + if (ret == -EAGAIN) { + usleep_range(1000, 2000); + try_count++; + } + } while (ret == -EAGAIN && try_count < 50); if (ret) { DXG_ERR("vmbus_sendpacket failed: %x", ret); spin_lock_irq(&channel->packet_list_mutex);

