Page MenuHomeFreeBSD

D26486.diff
No OneTemporary

D26486.diff

Index: head/sys/dev/hyperv/pcib/vmbus_pcib.c
===================================================================
--- head/sys/dev/hyperv/pcib/vmbus_pcib.c
+++ head/sys/dev/hyperv/pcib/vmbus_pcib.c
@@ -117,6 +117,31 @@
mtx_unlock(&c->lock);
}
+/*
+ * Return: 0 if completed, a non-zero value if timed out.
+ */
+static int
+wait_for_completion_timeout(struct completion *c, int timeout)
+{
+ int ret;
+
+ mtx_lock(&c->lock);
+
+ if (c->done == 0)
+ mtx_sleep(c, &c->lock, 0, "hvwfc", timeout);
+
+ if (c->done > 0) {
+ c->done--;
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+
+ mtx_unlock(&c->lock);
+
+ return (ret);
+}
+
#define PCI_MAKE_VERSION(major, minor) ((uint32_t)(((major) << 16) | (major)))
enum {
@@ -438,6 +463,25 @@
struct tran_int_desc int_desc;
};
+/*
+ * It is possible the device is revoked during initialization.
+ * Check if this happens during wait.
+ * Return: 0 if response arrived, ENODEV if device revoked.
+ */
+static int
+wait_for_response(struct hv_pcibus *hbus, struct completion *c)
+{
+ do {
+ if (vmbus_chan_is_revoked(hbus->sc->chan)) {
+ device_printf(hbus->pcib,
+ "The device is revoked.\n");
+ return (ENODEV);
+ }
+ } while (wait_for_completion_timeout(c, hz /10) != 0);
+
+ return 0;
+}
+
static void
hv_pci_generic_compl(void *context, struct pci_response *resp,
int resp_packet_size)
@@ -568,7 +612,9 @@
if (ret)
goto err;
- wait_for_completion(&comp_pkt.host_event);
+ if (wait_for_response(hbus, &comp_pkt.host_event))
+ goto err;
+
free_completion(&comp_pkt.host_event);
hpdev->desc = *desc;
@@ -1011,11 +1057,16 @@
ret = vmbus_chan_send(hbus->sc->chan, VMBUS_CHANPKT_TYPE_INBAND,
VMBUS_CHANPKT_FLAG_RC, version_req, sizeof(*version_req),
(uint64_t)(uintptr_t)&ctxt.pkt);
- if (ret)
+ if (!ret)
+ ret = wait_for_response(hbus, &comp_pkt.host_event);
+
+ if (ret) {
+ device_printf(hbus->pcib,
+ "vmbus_pcib failed to request version: %d\n",
+ ret);
goto out;
+ }
- wait_for_completion(&comp_pkt.host_event);
-
if (comp_pkt.completion_status < 0) {
device_printf(hbus->pcib,
"vmbus_pcib version negotiation failed: %x\n",
@@ -1072,11 +1123,12 @@
ret = vmbus_chan_send(hbus->sc->chan, VMBUS_CHANPKT_TYPE_INBAND,
VMBUS_CHANPKT_FLAG_RC, d0_entry, sizeof(*d0_entry),
(uint64_t)(uintptr_t)&ctxt.pkt);
+ if (!ret)
+ ret = wait_for_response(hbus, &comp_pkt.host_event);
+
if (ret)
goto out;
- wait_for_completion(&comp_pkt.host_event);
-
if (comp_pkt.completion_status < 0) {
device_printf(hbus->pcib, "vmbus_pcib failed to enable D0\n");
ret = EPROTO;
@@ -1125,14 +1177,14 @@
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
&pkt->message, sizeof(*res_assigned),
(uint64_t)(uintptr_t)pkt);
- if (ret) {
- free_completion(&comp_pkt.host_event);
- break;
- }
+ if (!ret)
+ ret = wait_for_response(hbus, &comp_pkt.host_event);
- wait_for_completion(&comp_pkt.host_event);
free_completion(&comp_pkt.host_event);
+ if (ret)
+ break;
+
if (comp_pkt.completion_status < 0) {
ret = EPROTO;
device_printf(hbus->pcib,
@@ -1413,9 +1465,11 @@
goto vmbus_close;
ret = hv_pci_query_relations(hbus);
+ if (!ret)
+ ret = wait_for_response(hbus, hbus->query_comp);
+
if (ret)
goto vmbus_close;
- wait_for_completion(hbus->query_comp);
ret = hv_pci_enter_d0(hbus);
if (ret)

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 8, 3:35 AM (21 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14526821
Default Alt Text
D26486.diff (3 KB)

Event Timeline