Date: Sun, 30 Dec 2007 05:18:11 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 132025 for review Message-ID: <200712300518.lBU5IBvm047604@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=132025 Change 132025 by kmacy@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(); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712300518.lBU5IBvm047604>