svn commit: r297176 - head/sys/dev/hyperv/vmbus

Sepherosa Ziehau sephe at FreeBSD.org
Tue Mar 22 05:48:53 UTC 2016


Author: sephe
Date: Tue Mar 22 05:48:51 2016
New Revision: 297176
URL: https://svnweb.freebsd.org/changeset/base/297176

Log:
  hyperv/evttimer: Use an independent message slot so that it can work
  
  Using the same message slot as the other types of the messages has
  the side effect that the event timer message could be deferred to
  the swi threads to run (lacking of trapframe and the original code
  didn't even handle that, so the event timer was actually broken).
  
  As of this commit we use an independent message slot for event timer,
  so that we could handle all of event timer messages in the interrupt
  handler directly.  Note, the message slot for event timer is still
  bind to the same interrupt vector as the other types of messages.
  
  Submitted by:	Jun Su <junsu microsoft com>
  Reviewed by:	sephe
  Discussed with: Jun Su <junsu microsoft com>, Dexuan Cui <decui microsoft com>
  MFC after:	1 week
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D5696

Modified:
  head/sys/dev/hyperv/vmbus/hv_et.c
  head/sys/dev/hyperv/vmbus/hv_hv.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h

Modified: head/sys/dev/hyperv/vmbus/hv_et.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_et.c	Tue Mar 22 01:09:15 2016	(r297175)
+++ head/sys/dev/hyperv/vmbus/hv_et.c	Tue Mar 22 05:48:51 2016	(r297176)
@@ -60,7 +60,7 @@ hv_et_start(struct eventtimer *et, sbint
 
 	timer_cfg.as_uint64 = 0;
 	timer_cfg.auto_enable = 1;
-	timer_cfg.sintx = HV_VMBUS_MESSAGE_SINT;
+	timer_cfg.sintx = HV_VMBUS_TIMER_SINT;
 
 	periodticks[curcpu] = sbintime2tick(periodtime);
 	if (firsttime == 0)

Modified: head/sys/dev/hyperv/vmbus/hv_hv.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_hv.c	Tue Mar 22 01:09:15 2016	(r297175)
+++ head/sys/dev/hyperv/vmbus/hv_hv.c	Tue Mar 22 05:48:51 2016	(r297176)
@@ -368,6 +368,9 @@ hv_vmbus_synic_init(void *arg)
 	wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
 	    shared_sint.as_uint64_t);
 
+	wrmsr(HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
+	    shared_sint.as_uint64_t);
+
 	/* Enable the global synic bit */
 	sctrl.as_uint64_t = rdmsr(HV_X64_MSR_SCONTROL);
 	sctrl.u.enable = 1;
@@ -404,12 +407,23 @@ void hv_vmbus_synic_cleanup(void *arg)
 	shared_sint.u.masked = 1;
 
 	/*
-	 * Disable the interrupt
+	 * Disable the interrupt 0
 	 */
 	wrmsr(
 	    HV_X64_MSR_SINT0 + HV_VMBUS_MESSAGE_SINT,
 	    shared_sint.as_uint64_t);
 
+	shared_sint.as_uint64_t = rdmsr(
+	    HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT);
+
+	shared_sint.u.masked = 1;
+
+	/*
+	 * Disable the interrupt 1
+	 */
+	wrmsr(
+	    HV_X64_MSR_SINT0 + HV_VMBUS_TIMER_SINT,
+	    shared_sint.as_uint64_t);
 	simp.as_uint64_t = rdmsr(HV_X64_MSR_SIMP);
 	simp.u.simp_enabled = 0;
 	simp.u.base_simp_gpa = 0;

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Tue Mar 22 01:09:15 2016	(r297175)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Tue Mar 22 05:48:51 2016	(r297176)
@@ -175,12 +175,15 @@ hv_vmbus_isr(struct trapframe *frame)
 
 	/* Check if there are actual msgs to be process */
 	page_addr = hv_vmbus_g_context.syn_ic_msg_page[cpu];
-	msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT;
+	msg = (hv_vmbus_message*) page_addr + HV_VMBUS_TIMER_SINT;
 
 	/* we call eventtimer process the message */
 	if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) {
 		msg->header.message_type = HV_MESSAGE_TYPE_NONE;
 
+		/* call intrrupt handler of event timer */
+		hv_et_intr(frame);
+
 		/*
 		 * Make sure the write to message_type (ie set to
 		 * HV_MESSAGE_TYPE_NONE) happens before we read the
@@ -197,10 +200,9 @@ hv_vmbus_isr(struct trapframe *frame)
 			 */
 			wrmsr(HV_X64_MSR_EOM, 0);
 		}
-		hv_et_intr(frame);
-		return (FILTER_HANDLED);
 	}
 
+	msg = (hv_vmbus_message*) page_addr + HV_VMBUS_MESSAGE_SINT;
 	if (msg->header.message_type != HV_MESSAGE_TYPE_NONE) {
 		swi_sched(hv_vmbus_g_context.msg_swintr[cpu], 0);
 	}

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue Mar 22 01:09:15 2016	(r297175)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue Mar 22 05:48:51 2016	(r297176)
@@ -180,7 +180,8 @@ enum {
 	HV_VMBUS_EVENT_PORT_ID		= 2,
 	HV_VMBUS_MONITOR_CONNECTION_ID	= 3,
 	HV_VMBUS_MONITOR_PORT_ID	= 3,
-	HV_VMBUS_MESSAGE_SINT		= 2
+	HV_VMBUS_MESSAGE_SINT		= 2,
+	HV_VMBUS_TIMER_SINT		= 4,
 };
 
 #define HV_PRESENT_BIT		0x80000000


More information about the svn-src-all mailing list