PERFORCE change 132025 for review

Kip Macy kmacy at FreeBSD.org
Sat Dec 29 21:18:12 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=132025

Change 132025 by kmacy at pandemonium:kmacy:xen31 on 2007/12/30 05:17:47

	update event channel code
	fix pic registration so that we actually get clock interrupts
	and console interrupts now
	next up - block device interrupts

Affected files ...

.. //depot/projects/xen31/sys/dev/xen/blkfront/blkfront.c#4 edit
.. //depot/projects/xen31/sys/dev/xen/console/xencons_ring.c#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/evtchn.h#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen-os.h#3 edit
.. //depot/projects/xen31/sys/i386/include/xen/xen_intr.h#2 edit
.. //depot/projects/xen31/sys/i386/xen/xen_bus.c#1 add
.. //depot/projects/xen31/sys/xen/evtchn/evtchn.c#3 edit
.. //depot/projects/xen31/sys/xen/xenbus/xenbus_comms.c#3 edit
.. //depot/projects/xen31/sys/xen/xenbus/xenbus_xs.c#6 edit

Differences ...

==== //depot/projects/xen31/sys/dev/xen/blkfront/blkfront.c#4 (text+ko) ====

@@ -378,11 +378,8 @@
 	}
 	info->ring_ref = err;
 
-	err = xenbus_alloc_evtchn(dev, &info->evtchn);
-	if (err)
-		goto fail;
-	err = bind_evtchn_to_irqhandler(info->evtchn, "xbd", 
-					(driver_intr_t *)blkif_int,
+	err = bind_listening_port_to_irqhandler(dev->otherend_id,
+		"xbd", (driver_intr_t *)blkif_int,
 					info, INTR_TYPE_BIO | INTR_MPSAFE, NULL);
 	if (err <= 0) {
 		xenbus_dev_fatal(dev, err,
@@ -421,7 +418,11 @@
 		break;
 
 	case XenbusStateClosing:
-		panic("not implemented");
+		if (info->users > 0)
+			xenbus_dev_error(dev, -EBUSY,
+					 "Device in use; refusing to close");
+		else
+			blkfront_closing(dev);
 #ifdef notyet
 		bd = bdget(info->dev);
 		if (bd == NULL)

==== //depot/projects/xen31/sys/dev/xen/console/xencons_ring.c#3 (text+ko) ====

@@ -101,7 +101,7 @@
 	if (!xen_start_info->console_evtchn)
 		return 0;
 
-	err = bind_evtchn_to_irqhandler(xen_start_info->console_evtchn,
+	err = bind_caller_port_to_irqhandler(xen_start_info->console_evtchn,
 					"xencons", handle_input, NULL,
 					INTR_TYPE_MISC | INTR_MPSAFE, NULL);
 	if (err) {

==== //depot/projects/xen31/sys/i386/include/xen/evtchn.h#3 (text+ko) ====


==== //depot/projects/xen31/sys/i386/include/xen/xen-os.h#3 (text+ko) ====

@@ -118,15 +118,16 @@
                 preempt_enable_no_resched();                            \
 } while (0)
 
-
+/*
+ * Add critical_{enter, exit}?
+ *
+ */
 #define __save_and_cli(x)                                               \
 do {                                                                    \
         vcpu_info_t *_vcpu;                                             \
-        preempt_disable();                                              \
         _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
         (x) = _vcpu->evtchn_upcall_mask;                                \
         _vcpu->evtchn_upcall_mask = 1;                                  \
-        preempt_enable_no_resched();                                    \
         barrier();                                                      \
 } while (0)
 

==== //depot/projects/xen31/sys/i386/include/xen/xen_intr.h#2 (text+ko) ====

@@ -30,12 +30,25 @@
 extern void unbind_from_irq(int irq);
 
 extern void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu);
-extern int bind_evtchn_to_irqhandler(unsigned int evtchn, const char *devname,
-                                     driver_intr_t handler, void *arg, unsigned long irqflags, void **cookiep);
+extern int bind_caller_port_to_irqhandler(unsigned int caller_port,
+	const char *devname, driver_intr_t handler, void *arg,
+	unsigned long irqflags, void **cookiep);
+extern int bind_listening_port_to_irqhandler(unsigned int remote_domain,
+	const char *devname, driver_intr_t handler, void *arg, unsigned long irqflags,
+	void **cookiep);
 extern int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, const char *devname,
 									 driver_filter_t filter, driver_intr_t handler, unsigned long irqflags);
 extern int bind_ipi_to_irqhandler(unsigned int ipi, unsigned int cpu, const char *devname,
 									 driver_intr_t handler, unsigned long irqflags);
+extern int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
+	                                             unsigned int remote_port,
+	                                             const char *devname,
+	                                             driver_filter_t filter,
+	                                             driver_intr_t handler,
+	                                             unsigned long irqflags);
+
+
+
 extern void unbind_from_irqhandler(unsigned int evtchn, void *dev_id);
 static __inline__ int irq_cannonicalize(int irq)
 {

==== //depot/projects/xen31/sys/xen/evtchn/evtchn.c#3 (text+ko) ====

@@ -82,10 +82,6 @@
 	struct xenpic_intsrc xp_pins[0]; 
 }; 
 
-
-
-
-
 #define TODO            printf("%s: not implemented!\n", __func__) 
 
 /* IRQ <-> event-channel mappings. */
@@ -94,7 +90,15 @@
 /* Packed IRQ information: binding type, sub-type index, and event channel. */
 static uint32_t irq_info[NR_IRQS];
 /* Binding types. */
-enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
+enum {
+	IRQT_UNBOUND,
+	IRQT_PIRQ,
+	IRQT_VIRQ,
+	IRQT_IPI,
+	IRQT_LOCAL_PORT,
+	IRQT_CALLER_PORT
+};
+
 /* Constructor for packed IRQ information. */
 #define mk_irq_info(type, index, evtchn)				\
 	(((uint32_t)(type) << 24) | ((uint32_t)(index) << 16) | (uint32_t)(evtchn))
@@ -227,25 +231,82 @@
 	return irq;
 }
 
-static int 
-bind_evtchn_to_irq(unsigned int evtchn)
+static int
+bind_caller_port_to_irq(unsigned int caller_port)
+{
+        int irq;
+
+        mtx_lock_spin(&irq_mapping_update_lock);
+
+        if ((irq = evtchn_to_irq[caller_port]) == -1) {
+                if ((irq = find_unbound_irq()) < 0)
+                        goto out;
+
+                evtchn_to_irq[caller_port] = irq;
+                irq_info[irq] = mk_irq_info(IRQT_CALLER_PORT, 0, caller_port);
+        }
+
+        irq_bindcount[irq]++;
+
+ out:
+        mtx_unlock_spin(&irq_mapping_update_lock);
+        return irq;
+}
+
+static int
+bind_local_port_to_irq(unsigned int local_port)
+{
+        int irq;
+
+        mtx_lock_spin(&irq_mapping_update_lock);
+
+        PANIC_IF(evtchn_to_irq[local_port] != -1);
+
+        if ((irq = find_unbound_irq()) < 0) {
+                struct evtchn_close close = { .port = local_port };
+                PANIC_IF(HYPERVISOR_event_channel_op(EVTCHNOP_close, &close));
+		
+                goto out;
+        }
+
+        evtchn_to_irq[local_port] = irq;
+        irq_info[irq] = mk_irq_info(IRQT_LOCAL_PORT, 0, local_port);
+        irq_bindcount[irq]++;
+
+ out:
+        mtx_unlock_spin(&irq_mapping_update_lock);
+        return irq;
+}
+
+static int
+bind_listening_port_to_irq(unsigned int remote_domain)
+{
+        struct evtchn_alloc_unbound alloc_unbound;
+        int err;
+
+        alloc_unbound.dom        = DOMID_SELF;
+        alloc_unbound.remote_dom = remote_domain;
+
+        err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+                                          &alloc_unbound);
+
+        return err ? : bind_local_port_to_irq(alloc_unbound.port);
+}
+
+static int
+bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
+    unsigned int remote_port)
 {
-	int irq;
+        struct evtchn_bind_interdomain bind_interdomain;
+        int err;
 
-	mtx_lock_spin(&irq_mapping_update_lock);
-	
-	if ((irq = evtchn_to_irq[evtchn]) == -1) {
-		irq = find_unbound_irq();
-		evtchn_to_irq[evtchn] = irq;
-		irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
-	}
+        bind_interdomain.remote_dom  = remote_domain;
+        bind_interdomain.remote_port = remote_port;
 
-	irq_bindcount[irq]++;
-	intr_register_source(&xp->xp_pins[irq].xp_intsrc);
+        err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+                                          &bind_interdomain);
 
-	mtx_unlock_spin(&irq_mapping_update_lock);
-    
-	return irq;
+        return err ? : bind_local_port_to_irq(bind_interdomain.local_port);
 }
 
 static int 
@@ -348,7 +409,30 @@
 }
 
 int 
-bind_evtchn_to_irqhandler(unsigned int evtchn,
+bind_caller_port_to_irqhandler(unsigned int caller_port,
+			  const char *devname,
+			  driver_intr_t handler,
+			  void *arg,
+			  unsigned long irqflags,
+                          void **cookiep)
+{
+	unsigned int irq;
+	int retval;
+
+	irq = bind_caller_port_to_irq(caller_port);
+	intr_register_source(&xp->xp_pins[irq].xp_intsrc);
+	retval = intr_add_handler(devname, irq, NULL, handler, arg, irqflags, cookiep);
+	if (retval != 0) {
+		unbind_from_irq(irq);
+		return -retval;
+	}
+
+	return irq;
+}
+
+int 
+bind_listening_port_to_irqhandler(
+	                  unsigned int remote_domain,
 			  const char *devname,
 			  driver_intr_t handler,
 			  void *arg,
@@ -358,7 +442,7 @@
 	unsigned int irq;
 	int retval;
 
-	irq = bind_evtchn_to_irq(evtchn);
+	irq = bind_listening_port_to_irq(remote_domain);
 	intr_register_source(&xp->xp_pins[irq].xp_intsrc);
 	retval = intr_add_handler(devname, irq, NULL, handler, arg, irqflags, cookiep);
 	if (retval != 0) {
@@ -370,6 +454,29 @@
 }
 
 int 
+bind_interdomain_evtchn_to_irqhandler(
+	                unsigned int remote_domain,
+	                unsigned int remote_port,
+			const char *devname,
+			driver_filter_t filter,
+			driver_intr_t handler,
+			unsigned long irqflags)
+{
+	unsigned int irq;
+	int retval;
+
+	irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port);
+	intr_register_source(&xp->xp_pins[irq].xp_intsrc);
+	retval = intr_add_handler(devname, irq, filter, handler, NULL, irqflags, NULL);
+	if (retval != 0) {
+		unbind_from_irq(irq);
+		return -retval;
+	}
+
+	return irq;
+}
+
+int 
 bind_virq_to_irqhandler(unsigned int virq,
 			unsigned int cpu,
 			const char *devname,
@@ -405,13 +512,14 @@
 	retval = intr_add_handler(devname, irq, NULL, handler, NULL, irqflags, NULL);
 	if (retval != 0) {
 		unbind_from_irq(irq);
-		return retval;
+		return -retval;
 	}
 
 	return irq;
 }
 
-void unbind_from_irqhandler(unsigned int irq, void *dev_id)
+void
+unbind_from_irqhandler(unsigned int irq, void *dev_id)
 {
 	if (dev_id)
 		intr_remove_handler(dev_id); /* XXX */
@@ -420,7 +528,8 @@
 
 #if 0
 /* Rebind an evtchn so that it gets delivered to a specific cpu */
-static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
+static void
+rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
 {
 	evtchn_op_t op = { .cmd = EVTCHNOP_bind_vcpu };
 	int evtchn;
@@ -789,14 +898,14 @@
 		return;
 	}
 
-	synch_clear_bit(port, &s->evtchn_mask[0]);
+	synch_clear_bit(port, &s->evtchn_mask);
 
 	/*
 	 * The following is basically the equivalent of 'hw_resend_irq'. Just
 	 * like a real IO-APIC we 'lose the interrupt edge' if the channel is
 	 * masked.
 	 */
-	if (synch_test_bit(port, &s->evtchn_pending[0]) && 
+	if (synch_test_bit(port, &s->evtchn_pending) && 
 	    !synch_test_and_set_bit(port / BITS_PER_LONG,
 				    &vcpu_info->evtchn_pending_sel)) {
 		vcpu_info->evtchn_upcall_pending = 1;
@@ -912,6 +1021,13 @@
 	xp->xp_numintr = NR_IRQS;
 	bzero(xp->xp_pins, sizeof(struct xenpic_intsrc) * NR_IRQS);
 
+
+	/* We need to register our PIC's beforehand */
+	if (intr_register_pic(&xenpic_pirq_template))
+		panic("XEN: intr_register_pic() failure");
+	if (intr_register_pic(&xenpic_dynirq_template))
+		panic("XEN: intr_register_pic() failure");
+
 	/*
 	 * Initialize the dynamic IRQ's - we initialize the structures, but
 	 * we do not bind them (bind_evtchn_to_irqhandle() does this)
@@ -924,14 +1040,9 @@
 		tpin = &pin[dynirq_to_irq(i)];
 		tpin->xp_intsrc.is_pic = xp->xp_dynirq_pic;
 		tpin->xp_vector = dynirq_to_irq(i);
+		
+                intr_register_source(&tpin->xp_intsrc);
 	}
-
-	/* We need to register our PIC's beforehand */
-	if (intr_register_pic(&xenpic_pirq_template))
-		panic("XEN: intr_register_pic() failure");
-	if (intr_register_pic(&xenpic_dynirq_template))
-		panic("XEN: intr_register_pic() failure");
-
 	/*
 	 * Now, we go ahead and claim every PIRQ there is.
 	 */

==== //depot/projects/xen31/sys/xen/xenbus/xenbus_comms.c#3 (text+ko) ====

@@ -194,7 +194,7 @@
 		if (xenbus_irq)
 				unbind_from_irqhandler(xenbus_irq, &xb_waitq);
 
-		err = bind_evtchn_to_irqhandler(
+		err = bind_caller_port_to_irqhandler(
 				xen_start_info->store_evtchn, "xenbus", wake_waiting, NULL, INTR_TYPE_NET, NULL);
 		if (err <= 0) {
 				printk("XENBUS request irq failed %i\n", err);

==== //depot/projects/xen31/sys/xen/xenbus/xenbus_xs.c#6 (text+ko) ====

@@ -145,12 +145,12 @@
 		char *body;
 		int i;
 			 
-		if (HYPERVISOR_shared_info->evtchn_mask[curcpu] & 1) {
+		if (HYPERVISOR_shared_info->evtchn_mask[curcpu] & 0x2) {
 				/*
 				 * Give other domain time to run :-/
 				 */
-				for (i = 0; i < 1000; i++)
-						HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
+				for (i = 0; i < 5000; i++)
+						HYPERVISOR_yield();
 				xs_process_msg();
 		}
 		


More information about the p4-projects mailing list