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);

Reply via email to