Skip to content

Commit 5937795

Browse files
author
Iouri Tarassov
committed
Allow killing a process waiting for a VM bus message reply
Signed-off-by: Iouri Tarassov <iourit@linux.microsoft.com>
1 parent 9b075b1 commit 5937795

6 files changed

Lines changed: 56 additions & 102 deletions

File tree

drivers/hv/dxgkrnl/dxgadapter.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,8 @@ void dxgprocess_adapter_destroy(struct dxgprocess_adapter *adapter_info)
10451045
list_del(&device->device_list_entry);
10461046
device->device_list_entry.next = NULL;
10471047
mutex_unlock(&adapter_info->device_list_mutex);
1048+
dxgvmb_send_flush_device(device,
1049+
DXGDEVICE_FLUSHSCHEDULER_DEVICE_TERMINATE);
10481050
dxgdevice_destroy(device);
10491051
mutex_lock(&adapter_info->device_list_mutex);
10501052
}

drivers/hv/dxgkrnl/dxgkrnl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ struct dxgk_device_types {
6363
u32 virtual_monitor_device:1;
6464
};
6565

66+
enum dxgdevice_flushschedulerreason
67+
{
68+
DXGDEVICE_FLUSHSCHEDULER_DEVICE_TERMINATE = 4,
69+
};
70+
6671
enum dxgobjectstate {
6772
DXGOBJECTSTATE_CREATED,
6873
DXGOBJECTSTATE_ACTIVE,
@@ -757,6 +762,8 @@ struct d3dkmthandle dxgvmb_send_create_device(struct dxgadapter *adapter,
757762
int dxgvmb_send_destroy_device(struct dxgadapter *adapter,
758763
struct dxgprocess *process,
759764
struct d3dkmthandle h);
765+
int dxgvmb_send_flush_device(struct dxgdevice *device,
766+
enum dxgdevice_flushschedulerreason reason);
760767
struct d3dkmthandle
761768
dxgvmb_send_create_context(struct dxgadapter *adapter,
762769
struct dxgprocess *process,

drivers/hv/dxgkrnl/dxgmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
struct dxgglobal *dxgglobal;
2424
struct device *dxgglobaldev;
2525

26-
#define DXGKRNL_VERSION 0x2202
26+
#define DXGKRNL_VERSION 0x2216
2727
#define PCI_VENDOR_ID_MICROSOFT 0x1414
2828
#define PCI_DEVICE_ID_VIRTUAL_RENDER 0x008E
2929

drivers/hv/dxgkrnl/dxgvmbus.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ struct dxgvmbuspacket {
3737
void *buffer;
3838
u32 buffer_length;
3939
int status;
40+
bool completed;
4041
};
4142

4243
struct dxgvmb_ext_header {
@@ -354,6 +355,7 @@ void process_completion_packet(struct dxgvmbuschannel *channel,
354355
if (desc->trans_id == entry->request_id) {
355356
packet = entry;
356357
list_del(&packet->packet_list_entry);
358+
packet->completed = true;
357359
break;
358360
}
359361
}
@@ -436,6 +438,7 @@ int dxgvmb_send_sync_msg(struct dxgvmbuschannel *channel,
436438
packet->buffer = result;
437439
packet->buffer_length = result_size;
438440
packet->status = 0;
441+
packet->completed = false;
439442
spin_lock_irq(&channel->packet_list_mutex);
440443
list_add_tail(&packet->packet_list_entry, &channel->packet_list_head);
441444
spin_unlock_irq(&channel->packet_list_mutex);
@@ -452,7 +455,15 @@ int dxgvmb_send_sync_msg(struct dxgvmbuschannel *channel,
452455
}
453456

454457
dev_dbg(dxgglobaldev, "waiting completion: %llu", packet->request_id);
455-
wait_for_completion(&packet->wait);
458+
ret = wait_for_completion_killable(&packet->wait);
459+
if (ret) {
460+
pr_err("wait_for_complition failed: %x", ret);
461+
spin_lock_irq(&channel->packet_list_mutex);
462+
if (!packet->completed)
463+
list_del(&packet->packet_list_entry);
464+
spin_unlock_irq(&channel->packet_list_mutex);
465+
goto cleanup;
466+
}
456467
dev_dbg(dxgglobaldev, "completion done: %llu %x",
457468
packet->request_id, packet->status);
458469
ret = packet->status;
@@ -1071,6 +1082,32 @@ int dxgvmb_send_destroy_device(struct dxgadapter *adapter,
10711082
return ret;
10721083
}
10731084

1085+
int dxgvmb_send_flush_device(struct dxgdevice *device,
1086+
enum dxgdevice_flushschedulerreason reason)
1087+
{
1088+
int ret;
1089+
struct dxgkvmb_command_flushdevice *command;
1090+
struct dxgvmbusmsg msg = {.hdr = NULL};
1091+
struct dxgprocess *process = device->process;
1092+
1093+
ret = init_message(&msg, device->adapter, process, sizeof(*command));
1094+
if (ret)
1095+
goto cleanup;
1096+
command = (void *)msg.msg;
1097+
1098+
command_vgpu_to_host_init2(&command->hdr, DXGK_VMBCOMMAND_FLUSHDEVICE,
1099+
process->host_handle);
1100+
command->device = device->handle;
1101+
command->reason = reason;
1102+
1103+
ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size);
1104+
cleanup:
1105+
free_message(&msg, process);
1106+
if (ret)
1107+
dev_dbg(dxgglobaldev, "err: %s %d", __func__, ret);
1108+
return ret;
1109+
}
1110+
10741111
struct d3dkmthandle
10751112
dxgvmb_send_create_context(struct dxgadapter *adapter,
10761113
struct dxgprocess *process,

drivers/hv/dxgkrnl/dxgvmbus.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,13 @@ struct dxgkvmb_command_destroydevice {
396396
struct d3dkmthandle device;
397397
};
398398

399+
struct dxgkvmb_command_flushdevice
400+
{
401+
struct dxgkvmb_command_vgpu_to_host hdr;
402+
struct d3dkmthandle device;
403+
enum dxgdevice_flushschedulerreason reason;
404+
};
405+
399406
struct dxgkvmb_command_makeresident {
400407
struct dxgkvmb_command_vgpu_to_host hdr;
401408
struct d3dkmthandle device;

drivers/hv/dxgkrnl/ioctl.c

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -3594,7 +3594,7 @@ dxgk_wait_sync_object_cpu(struct dxgprocess *process, void *__user inargs)
35943594
async_host_event = NULL;
35953595
} else {
35963596
pr_err("Invalid event type");
3597-
DXGKRNL_ASSERT(FALSE);
3597+
DXGKRNL_ASSERT(0);
35983598
}
35993599
}
36003600
}
@@ -4395,81 +4395,6 @@ dxgk_flush_heap_transitions(struct dxgprocess *process, void *__user inargs)
43954395
return ret;
43964396
}
43974397

4398-
#ifdef DEBUG
4399-
static int handle_table_escape(struct dxgprocess *process,
4400-
struct d3dkmt_escape *args,
4401-
struct d3dkmt_ht_desc *cmdin)
4402-
{
4403-
int ret = 0;
4404-
struct d3dkmt_ht_desc cmd;
4405-
struct hmgrtable *table;
4406-
4407-
mutex_lock(&process->process_mutex);
4408-
cmd = *cmdin;
4409-
if (cmd.index >= 2) {
4410-
pr_err("invalid table index");
4411-
ret = -EINVAL;
4412-
goto cleanup;
4413-
}
4414-
table = process->test_handle_table[cmd.index];
4415-
if (table == NULL) {
4416-
table = vzalloc(sizeof(*table));
4417-
if (table == NULL) {
4418-
ret = -EINVAL;
4419-
goto cleanup;
4420-
}
4421-
hmgrtable_init(table, process);
4422-
process->test_handle_table[cmd.index] = table;
4423-
}
4424-
switch (cmd.command) {
4425-
case D3DKMT_HT_COMMAND_ALLOC:
4426-
cmd.handle = hmgrtable_alloc_handle_safe(table, cmd.object,
4427-
(enum hmgrentry_type)
4428-
cmd.object_type, true);
4429-
ret = copy_to_user(args->priv_drv_data, &cmd, sizeof(cmd));
4430-
if (ret)
4431-
ret = -EINVAL;
4432-
break;
4433-
case D3DKMT_HT_COMMAND_FREE:
4434-
hmgrtable_free_handle_safe(table,
4435-
(enum hmgrentry_type)cmd.object_type,
4436-
cmd.handle);
4437-
break;
4438-
case D3DKMT_HT_COMMAND_ASSIGN:
4439-
ret = hmgrtable_assign_handle_safe(table, cmd.object,
4440-
(enum hmgrentry_type)cmd.object_type,
4441-
cmd.handle);
4442-
break;
4443-
case D3DKMT_HT_COMMAND_GET:
4444-
hmgrtable_lock(table, DXGLOCK_SHARED);
4445-
cmd.object = hmgrtable_get_object_by_type(table,
4446-
(enum hmgrentry_type)
4447-
cmd.object_type,
4448-
cmd.handle);
4449-
hmgrtable_unlock(table, DXGLOCK_SHARED);
4450-
ret = copy_to_user(args->priv_drv_data, &cmd, sizeof(cmd));
4451-
if (ret)
4452-
ret = -EINVAL;
4453-
break;
4454-
case D3DKMT_HT_COMMAND_DESTROY:
4455-
if (table) {
4456-
hmgrtable_destroy(table);
4457-
vfree(table);
4458-
}
4459-
process->test_handle_table[cmd.index] = NULL;
4460-
break;
4461-
default:
4462-
ret = -EINVAL;
4463-
pr_err("unknoen handle table command");
4464-
break;
4465-
}
4466-
4467-
cleanup:
4468-
mutex_unlock(&process->process_mutex);
4469-
return ret;
4470-
}
4471-
#endif /* DEBUG */
4472-
44734398
static int
44744399
dxgk_escape(struct dxgprocess *process, void *__user inargs)
44754400
{
@@ -4497,30 +4422,6 @@ dxgk_escape(struct dxgprocess *process, void *__user inargs)
44974422
}
44984423
adapter_locked = true;
44994424

4500-
#ifdef DEBUG
4501-
if (args.type == D3DKMT_ESCAPE_DRT_TEST) {
4502-
struct d3dkmt_ht_desc drtcmd;
4503-
4504-
if (args.priv_drv_data_size >= sizeof(drtcmd)) {
4505-
ret = copy_from_user(&drtcmd,
4506-
args.priv_drv_data,
4507-
sizeof(drtcmd));
4508-
if (ret) {
4509-
ret = -EINVAL;
4510-
goto cleanup;
4511-
}
4512-
if (drtcmd.head.command ==
4513-
D3DKMT_DRT_TEST_COMMAND_HANDLETABLE) {
4514-
dxgadapter_release_lock_shared(adapter);
4515-
adapter_locked = false;
4516-
ret = handle_table_escape(process, &args,
4517-
&drtcmd);
4518-
goto cleanup;
4519-
}
4520-
}
4521-
}
4522-
#endif /* DEBUG */
4523-
45244425
args.adapter = adapter->host_handle;
45254426
ret = dxgvmb_send_escape(process, adapter, &args);
45264427

0 commit comments

Comments
 (0)