summaryrefslogtreecommitdiff
path: root/sys/dev/pv/hyperv.c
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2017-06-26 18:42:24 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2017-06-26 18:42:24 +0000
commit96e064c2d3e970f645b2f112541db8bd382fe04f (patch)
tree90076dcf5259cf92ddac4576751e28a3b71baf04 /sys/dev/pv/hyperv.c
parent8ce4e1fd0f314ea66d949780e2f91e3bcfd00102 (diff)
Rework the deferred interrupt loop
By performing a task_add an interrupt handler can rely on the taskq_thread to invoke it again with an additional benefit of being able to sched_pause when required. In the long run more than 99.8% of calls do not require an additional iteration.
Diffstat (limited to 'sys/dev/pv/hyperv.c')
-rw-r--r--sys/dev/pv/hyperv.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/sys/dev/pv/hyperv.c b/sys/dev/pv/hyperv.c
index 6ba01cdc6b9..8754c0a43de 100644
--- a/sys/dev/pv/hyperv.c
+++ b/sys/dev/pv/hyperv.c
@@ -106,6 +106,7 @@ int hv_channel_ring_create(struct hv_channel *, uint32_t);
void hv_channel_ring_destroy(struct hv_channel *);
void hv_channel_pause(struct hv_channel *);
uint hv_channel_unpause(struct hv_channel *);
+uint hv_channel_ready(struct hv_channel *);
extern void hv_attach_icdevs(struct hv_softc *);
int hv_attach_devices(struct hv_softc *);
@@ -1230,22 +1231,14 @@ void
hv_channel_intr(void *arg)
{
struct hv_channel *ch = arg;
- extern int ticks;
- int start = ticks;
- do {
+ if (hv_channel_ready(ch))
ch->ch_handler(ch->ch_ctx);
- if (hv_channel_unpause(ch) == 0)
- return;
-
- hv_channel_pause(ch);
-
-#if (defined(__amd64__) || defined(__i386__))
- __asm volatile("pause": : : "memory");
-#endif
- } while (ticks < start + 1);
+ if (hv_channel_unpause(ch) == 0)
+ return;
+ hv_channel_pause(ch);
hv_channel_schedule(ch);
}
@@ -1597,6 +1590,16 @@ hv_channel_unpause(struct hv_channel *ch)
return (avail);
}
+uint
+hv_channel_ready(struct hv_channel *ch)
+{
+ uint32_t avail;
+
+ hv_ring_avail(&ch->ch_rrd, NULL, &avail);
+
+ return (avail);
+}
+
/* How many PFNs can be referenced by the header */
#define HV_NPFNHDR ((VMBUS_MSG_DSIZE_MAX - \
sizeof(struct vmbus_chanmsg_gpadl_conn)) / sizeof(uint64_t))