From owner-p4-projects@FreeBSD.ORG Tue May 8 22:21:37 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 867A316A409; Tue, 8 May 2007 22:21:37 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4D47D16A402 for ; Tue, 8 May 2007 22:21:37 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id D61C913C43E for ; Tue, 8 May 2007 22:21:36 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l48MLa09068099 for ; Tue, 8 May 2007 22:21:36 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l48MLYJg068040 for perforce@freebsd.org; Tue, 8 May 2007 22:21:34 GMT (envelope-from jhb@freebsd.org) Date: Tue, 8 May 2007 22:21:34 GMT Message-Id: <200705082221.l48MLYJg068040@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Cc: Subject: PERFORCE change 119521 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 May 2007 22:21:38 -0000 http://perforce.freebsd.org/chv.cgi?CH=119521 Change 119521 by jhb@jhb_mutex on 2007/05/08 22:21:08 IFC @119518. Affected files ... .. //depot/projects/smpng/sys/amd64/acpica/madt.c#14 integrate .. //depot/projects/smpng/sys/amd64/amd64/intr_machdep.c#26 integrate .. //depot/projects/smpng/sys/amd64/amd64/io_apic.c#21 integrate .. //depot/projects/smpng/sys/amd64/amd64/local_apic.c#30 integrate .. //depot/projects/smpng/sys/amd64/amd64/mp_machdep.c#42 integrate .. //depot/projects/smpng/sys/amd64/amd64/mptable.c#12 integrate .. //depot/projects/smpng/sys/amd64/amd64/msi.c#6 integrate .. //depot/projects/smpng/sys/amd64/amd64/nexus.c#26 integrate .. //depot/projects/smpng/sys/amd64/include/apicvar.h#18 integrate .. //depot/projects/smpng/sys/amd64/include/intr_machdep.h#16 integrate .. //depot/projects/smpng/sys/amd64/include/vmparam.h#9 integrate .. //depot/projects/smpng/sys/amd64/isa/atpic.c#16 integrate .. //depot/projects/smpng/sys/arm/include/vmparam.h#8 integrate .. //depot/projects/smpng/sys/boot/common/loader.8#44 integrate .. //depot/projects/smpng/sys/conf/files#206 integrate .. //depot/projects/smpng/sys/conf/options#142 integrate .. //depot/projects/smpng/sys/contrib/opensolaris/uts/common/fs/zfs/dbuf.c#3 integrate .. //depot/projects/smpng/sys/contrib/opensolaris/uts/common/fs/zfs/dnode.c#2 integrate .. //depot/projects/smpng/sys/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c#2 integrate .. //depot/projects/smpng/sys/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c#2 integrate .. //depot/projects/smpng/sys/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c#3 integrate .. //depot/projects/smpng/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#4 integrate .. //depot/projects/smpng/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c#4 integrate .. //depot/projects/smpng/sys/contrib/opensolaris/uts/common/fs/zfs/zio.c#3 integrate .. //depot/projects/smpng/sys/dev/acpica/acpi.c#101 integrate .. //depot/projects/smpng/sys/dev/ata/ata-disk.c#64 integrate .. //depot/projects/smpng/sys/dev/bce/if_bce.c#16 integrate .. //depot/projects/smpng/sys/dev/bce/if_bcefw.h#2 integrate .. //depot/projects/smpng/sys/dev/bce/if_bcereg.h#7 integrate .. //depot/projects/smpng/sys/dev/isp/isp.c#57 integrate .. //depot/projects/smpng/sys/dev/isp/isp_freebsd.c#56 integrate .. //depot/projects/smpng/sys/dev/isp/isp_freebsd.h#41 integrate .. //depot/projects/smpng/sys/dev/isp/isp_pci.c#55 integrate .. //depot/projects/smpng/sys/dev/isp/isp_sbus.c#26 integrate .. //depot/projects/smpng/sys/dev/isp/isp_tpublic.h#14 integrate .. //depot/projects/smpng/sys/dev/mpt/mpt.c#23 integrate .. //depot/projects/smpng/sys/dev/mpt/mpt.h#22 integrate .. //depot/projects/smpng/sys/dev/mpt/mpt_cam.c#25 integrate .. //depot/projects/smpng/sys/dev/mpt/mpt_cam.h#6 integrate .. //depot/projects/smpng/sys/dev/mpt/mpt_pci.c#32 integrate .. //depot/projects/smpng/sys/dev/mpt/mpt_raid.c#11 integrate .. //depot/projects/smpng/sys/dev/mxge/eth_z8e.dat.gz.uu#5 integrate .. //depot/projects/smpng/sys/dev/mxge/ethp_z8e.dat.gz.uu#5 integrate .. //depot/projects/smpng/sys/dev/mxge/if_mxge.c#17 integrate .. //depot/projects/smpng/sys/dev/mxge/mxge_mcp.h#4 integrate .. //depot/projects/smpng/sys/dev/nve/if_nve.c#15 integrate .. //depot/projects/smpng/sys/dev/pci/pci.c#93 integrate .. //depot/projects/smpng/sys/dev/sound/pci/hda/hdac.c#13 integrate .. //depot/projects/smpng/sys/dev/sound/pci/hda/hdac_private.h#5 integrate .. //depot/projects/smpng/sys/dev/sound/pci/ich.c#51 integrate .. //depot/projects/smpng/sys/dev/sound/pcm/buffer.h#13 integrate .. //depot/projects/smpng/sys/dev/sound/pcm/sound.h#31 integrate .. //depot/projects/smpng/sys/dev/usb/if_rum.c#1 branch .. //depot/projects/smpng/sys/dev/usb/if_rumreg.h#1 branch .. //depot/projects/smpng/sys/dev/usb/if_rumvar.h#1 branch .. //depot/projects/smpng/sys/dev/usb/rt2573_ucode.h#1 branch .. //depot/projects/smpng/sys/dev/usb/ubsa.c#18 integrate .. //depot/projects/smpng/sys/dev/usb/usb_subr.c#40 integrate .. //depot/projects/smpng/sys/dev/usb/usbdevs#105 integrate .. //depot/projects/smpng/sys/geom/eli/g_eli_ctl.c#9 integrate .. //depot/projects/smpng/sys/geom/geom.h#50 integrate .. //depot/projects/smpng/sys/geom/geom_dev.c#45 integrate .. //depot/projects/smpng/sys/geom/geom_disk.c#50 integrate .. //depot/projects/smpng/sys/geom/geom_disk.h#7 integrate .. //depot/projects/smpng/sys/geom/geom_io.c#47 integrate .. //depot/projects/smpng/sys/geom/geom_slice.c#36 integrate .. //depot/projects/smpng/sys/geom/geom_subr.c#50 integrate .. //depot/projects/smpng/sys/geom/part/g_part.c#3 integrate .. //depot/projects/smpng/sys/geom/part/g_part.h#2 integrate .. //depot/projects/smpng/sys/geom/part/g_part_apm.c#2 integrate .. //depot/projects/smpng/sys/geom/part/g_part_gpt.c#2 integrate .. //depot/projects/smpng/sys/i386/acpica/madt.c#20 integrate .. //depot/projects/smpng/sys/i386/conf/GENERIC#88 integrate .. //depot/projects/smpng/sys/i386/conf/PAE#20 integrate .. //depot/projects/smpng/sys/i386/i386/intr_machdep.c#26 integrate .. //depot/projects/smpng/sys/i386/i386/io_apic.c#23 integrate .. //depot/projects/smpng/sys/i386/i386/local_apic.c#51 integrate .. //depot/projects/smpng/sys/i386/i386/mp_machdep.c#108 integrate .. //depot/projects/smpng/sys/i386/i386/mptable.c#20 integrate .. //depot/projects/smpng/sys/i386/i386/msi.c#6 integrate .. //depot/projects/smpng/sys/i386/i386/nexus.c#28 integrate .. //depot/projects/smpng/sys/i386/include/apicvar.h#27 integrate .. //depot/projects/smpng/sys/i386/include/intr_machdep.h#18 integrate .. //depot/projects/smpng/sys/i386/include/vmparam.h#10 integrate .. //depot/projects/smpng/sys/i386/isa/atpic.c#19 integrate .. //depot/projects/smpng/sys/ia64/ia64/machdep.c#109 integrate .. //depot/projects/smpng/sys/ia64/include/vmparam.h#13 integrate .. //depot/projects/smpng/sys/kern/kern_condvar.c#48 integrate .. //depot/projects/smpng/sys/kern/kern_intr.c#87 integrate .. //depot/projects/smpng/sys/kern/kern_mutex.c#147 integrate .. //depot/projects/smpng/sys/kern/kern_rwlock.c#16 integrate .. //depot/projects/smpng/sys/kern/kern_sx.c#47 integrate .. //depot/projects/smpng/sys/kern/kern_synch.c#116 integrate .. //depot/projects/smpng/sys/kern/uipc_socket.c#105 integrate .. //depot/projects/smpng/sys/kern/uipc_usrreq.c#77 integrate .. //depot/projects/smpng/sys/modules/Makefile#140 integrate .. //depot/projects/smpng/sys/modules/em/Makefile#7 integrate .. //depot/projects/smpng/sys/modules/rum/Makefile#1 branch .. //depot/projects/smpng/sys/net/ieee8023ad_lacp.c#5 integrate .. //depot/projects/smpng/sys/net/ieee8023ad_lacp.h#3 integrate .. //depot/projects/smpng/sys/net/if_lagg.c#4 integrate .. //depot/projects/smpng/sys/net/if_lagg.h#3 integrate .. //depot/projects/smpng/sys/net80211/ieee80211_amrr.c#2 integrate .. //depot/projects/smpng/sys/netinet/sctp.h#5 integrate .. //depot/projects/smpng/sys/netinet/sctp_asconf.c#8 integrate .. //depot/projects/smpng/sys/netinet/sctp_asconf.h#5 integrate .. //depot/projects/smpng/sys/netinet/sctp_auth.c#8 integrate .. //depot/projects/smpng/sys/netinet/sctp_auth.h#4 integrate .. //depot/projects/smpng/sys/netinet/sctp_bsd_addr.c#6 integrate .. //depot/projects/smpng/sys/netinet/sctp_bsd_addr.h#5 integrate .. //depot/projects/smpng/sys/netinet/sctp_constants.h#11 integrate .. //depot/projects/smpng/sys/netinet/sctp_crc32.c#5 integrate .. //depot/projects/smpng/sys/netinet/sctp_crc32.h#3 integrate .. //depot/projects/smpng/sys/netinet/sctp_header.h#4 integrate .. //depot/projects/smpng/sys/netinet/sctp_indata.c#12 integrate .. //depot/projects/smpng/sys/netinet/sctp_indata.h#5 integrate .. //depot/projects/smpng/sys/netinet/sctp_input.c#12 integrate .. //depot/projects/smpng/sys/netinet/sctp_input.h#3 integrate .. //depot/projects/smpng/sys/netinet/sctp_lock_bsd.h#5 integrate .. //depot/projects/smpng/sys/netinet/sctp_os.h#6 integrate .. //depot/projects/smpng/sys/netinet/sctp_os_bsd.h#10 integrate .. //depot/projects/smpng/sys/netinet/sctp_output.c#12 integrate .. //depot/projects/smpng/sys/netinet/sctp_output.h#6 integrate .. //depot/projects/smpng/sys/netinet/sctp_pcb.c#12 integrate .. //depot/projects/smpng/sys/netinet/sctp_pcb.h#10 integrate .. //depot/projects/smpng/sys/netinet/sctp_peeloff.c#8 integrate .. //depot/projects/smpng/sys/netinet/sctp_peeloff.h#3 integrate .. //depot/projects/smpng/sys/netinet/sctp_structs.h#9 integrate .. //depot/projects/smpng/sys/netinet/sctp_sysctl.c#4 integrate .. //depot/projects/smpng/sys/netinet/sctp_sysctl.h#4 integrate .. //depot/projects/smpng/sys/netinet/sctp_timer.c#9 integrate .. //depot/projects/smpng/sys/netinet/sctp_timer.h#3 integrate .. //depot/projects/smpng/sys/netinet/sctp_uio.h#10 integrate .. //depot/projects/smpng/sys/netinet/sctp_usrreq.c#13 integrate .. //depot/projects/smpng/sys/netinet/sctp_var.h#7 integrate .. //depot/projects/smpng/sys/netinet/sctputil.c#14 integrate .. //depot/projects/smpng/sys/netinet/sctputil.h#9 integrate .. //depot/projects/smpng/sys/netinet/tcp_debug.c#8 integrate .. //depot/projects/smpng/sys/netinet/tcp_input.c#105 integrate .. //depot/projects/smpng/sys/netinet/tcp_output.c#49 integrate .. //depot/projects/smpng/sys/netinet/tcp_subr.c#93 integrate .. //depot/projects/smpng/sys/netinet/tcp_syncache.c#59 integrate .. //depot/projects/smpng/sys/netinet/tcp_timer.c#36 integrate .. //depot/projects/smpng/sys/netinet/tcp_usrreq.c#62 integrate .. //depot/projects/smpng/sys/netinet/tcp_var.h#51 integrate .. //depot/projects/smpng/sys/netinet/udp_usrreq.c#77 integrate .. //depot/projects/smpng/sys/netinet6/in6_proto.c#19 integrate .. //depot/projects/smpng/sys/netinet6/nd6.c#41 integrate .. //depot/projects/smpng/sys/netinet6/nd6_nbr.c#25 integrate .. //depot/projects/smpng/sys/netinet6/sctp6_usrreq.c#11 integrate .. //depot/projects/smpng/sys/netinet6/sctp6_var.h#4 integrate .. //depot/projects/smpng/sys/powerpc/include/vmparam.h#6 integrate .. //depot/projects/smpng/sys/sparc64/include/vmparam.h#14 integrate .. //depot/projects/smpng/sys/sun4v/include/vmparam.h#3 integrate .. //depot/projects/smpng/sys/sys/disk.h#14 integrate .. //depot/projects/smpng/sys/sys/interrupt.h#22 integrate .. //depot/projects/smpng/sys/sys/rwlock.h#10 integrate .. //depot/projects/smpng/sys/sys/sx.h#27 integrate .. //depot/projects/smpng/sys/vm/vm_page.c#91 integrate .. //depot/projects/smpng/sys/vm/vm_page.h#39 integrate Differences ... ==== //depot/projects/smpng/sys/amd64/acpica/madt.c#14 (text+ko) ==== @@ -28,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/acpica/madt.c,v 1.23 2007/03/22 18:16:38 jkim Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/acpica/madt.c,v 1.24 2007/05/08 22:01:02 jhb Exp $"); #include #include @@ -53,21 +53,18 @@ #include #include -#define NIOAPICS 32 /* Max number of I/O APICs */ -#define NLAPICS 32 /* Max number of local APICs */ - typedef void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg); /* These two arrays are indexed by APIC IDs. */ struct ioapic_info { void *io_apic; UINT32 io_vector; -} ioapics[NIOAPICS]; +} ioapics[MAX_APIC_ID + 1]; struct lapic_info { u_int la_enabled:1; u_int la_acpi_id:8; -} lapics[NLAPICS]; +} lapics[MAX_APIC_ID + 1]; static int madt_found_sci_override; static ACPI_TABLE_MADT *madt; @@ -393,7 +390,7 @@ } /* Third, we register all the I/O APIC's. */ - for (i = 0; i < NIOAPICS; i++) + for (i = 0; i <= MAX_APIC_ID; i++) if (ioapics[i].io_apic != NULL) ioapic_register(ioapics[i].io_apic); @@ -450,7 +447,7 @@ "enabled" : "disabled"); if (!(proc->LapicFlags & ACPI_MADT_ENABLED)) break; - if (proc->Id >= NLAPICS) + if (proc->Id > MAX_APIC_ID) panic("%s: CPU ID %u too high", __func__, proc->Id); la = &lapics[proc->Id]; KASSERT(la->la_enabled == 0, @@ -479,7 +476,7 @@ "MADT: Found IO APIC ID %u, Interrupt %u at %p\n", apic->Id, apic->GlobalIrqBase, (void *)(uintptr_t)apic->Address); - if (apic->Id >= NIOAPICS) + if (apic->Id > MAX_APIC_ID) panic("%s: I/O APIC ID %u too high", __func__, apic->Id); if (ioapics[apic->Id].io_apic != NULL) @@ -545,7 +542,7 @@ { int i; - for (i = 0; i < NLAPICS; i++) { + for (i = 0; i <= MAX_APIC_ID; i++) { if (!lapics[i].la_enabled) continue; if (lapics[i].la_acpi_id != acpi_id) @@ -566,7 +563,7 @@ int i, best; best = -1; - for (i = 0; i < NIOAPICS; i++) { + for (i = 0; i <= MAX_APIC_ID; i++) { if (ioapics[i].io_apic == NULL || ioapics[i].io_vector > intr) continue; ==== //depot/projects/smpng/sys/amd64/amd64/intr_machdep.c#26 (text+ko) ==== @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/amd64/amd64/intr_machdep.c,v 1.30 2007/03/06 17:16:46 jhb Exp $ + * $FreeBSD: src/sys/amd64/amd64/intr_machdep.c,v 1.32 2007/05/08 21:29:12 jhb Exp $ */ /* @@ -43,13 +43,14 @@ #include #include #include -#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -71,9 +72,16 @@ static int intrcnt_index; static struct intsrc *interrupt_sources[NUM_IO_INTS]; -static struct mtx intr_table_lock; +static struct sx intr_table_lock; +static struct mtx intrcnt_lock; static STAILQ_HEAD(, pic) pics; +#ifdef INTR_FILTER +static void intr_eoi_src(void *arg); +static void intr_disab_eoi_src(void *arg); +static void intr_event_stray(void *cookie); +#endif + #ifdef SMP static int assign_cpu; @@ -109,14 +117,14 @@ { int error; - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); if (intr_pic_registered(pic)) error = EBUSY; else { STAILQ_INSERT_TAIL(&pics, pic, pics); error = 0; } - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); return (error); } @@ -134,20 +142,26 @@ vector = isrc->is_pic->pic_vector(isrc); if (interrupt_sources[vector] != NULL) return (EEXIST); +#ifdef INTR_FILTER error = intr_event_create(&isrc->is_event, isrc, 0, + (mask_fn)isrc->is_pic->pic_enable_source, + intr_eoi_src, intr_disab_eoi_src, "irq%d:", vector); +#else + error = intr_event_create(&isrc->is_event, isrc, 0, (mask_fn)isrc->is_pic->pic_enable_source, "irq%d:", vector); +#endif if (error) return (error); - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); if (interrupt_sources[vector] != NULL) { - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); intr_event_destroy(isrc->is_event); return (EEXIST); } intrcnt_register(isrc); interrupt_sources[vector] = isrc; - isrc->is_enabled = 0; - mtx_unlock_spin(&intr_table_lock); + isrc->is_handlers = 0; + sx_xunlock(&intr_table_lock); return (0); } @@ -171,19 +185,18 @@ error = intr_event_add_handler(isrc->is_event, name, filter, handler, arg, intr_priority(flags), flags, cookiep); if (error == 0) { + sx_xlock(&intr_table_lock); intrcnt_updatename(isrc); - mtx_lock_spin(&intr_table_lock); - if (!isrc->is_enabled) { - isrc->is_enabled = 1; + isrc->is_handlers++; + if (isrc->is_handlers == 1) { #ifdef SMP if (assign_cpu) intr_assign_next_cpu(isrc); #endif - mtx_unlock_spin(&intr_table_lock); isrc->is_pic->pic_enable_intr(isrc); - } else - mtx_unlock_spin(&intr_table_lock); - isrc->is_pic->pic_enable_source(isrc); + isrc->is_pic->pic_enable_source(isrc); + } + sx_xunlock(&intr_table_lock); } return (error); } @@ -196,8 +209,16 @@ isrc = intr_handler_source(cookie); error = intr_event_remove_handler(cookie); - if (error == 0) + if (error == 0) { + sx_xlock(&intr_table_lock); + isrc->is_handlers--; + if (isrc->is_handlers == 0) { + isrc->is_pic->pic_disable_source(isrc, PIC_NO_EOI); + isrc->is_pic->pic_disable_intr(isrc); + } intrcnt_updatename(isrc); + sx_xunlock(&intr_table_lock); + } return (error); } @@ -212,11 +233,82 @@ return (isrc->is_pic->pic_config_intr(isrc, trig, pol)); } +#ifdef INTR_FILTER void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame) { struct thread *td; struct intr_event *ie; + int vector; + + td = curthread; + + /* + * We count software interrupts when we process them. The + * code here follows previous practice, but there's an + * argument for counting hardware interrupts when they're + * processed too. + */ + (*isrc->is_count)++; + PCPU_LAZY_INC(cnt.v_intr); + + ie = isrc->is_event; + + /* + * XXX: We assume that IRQ 0 is only used for the ISA timer + * device (clk). + */ + vector = isrc->is_pic->pic_vector(isrc); + if (vector == 0) + clkintr_pending = 1; + + if (intr_event_handle(ie, frame) != 0) + intr_event_stray(isrc); +} + +static void +intr_event_stray(void *cookie) +{ + struct intsrc *isrc; + + isrc = cookie; + /* + * For stray interrupts, mask and EOI the source, bump the + * stray count, and log the condition. + */ + isrc->is_pic->pic_disable_source(isrc, PIC_EOI); + (*isrc->is_straycount)++; + if (*isrc->is_straycount < MAX_STRAY_LOG) + log(LOG_ERR, "stray irq%d\n", isrc->is_pic->pic_vector(isrc)); + else if (*isrc->is_straycount == MAX_STRAY_LOG) + log(LOG_CRIT, + "too many stray irq %d's: not logging anymore\n", + isrc->is_pic->pic_vector(isrc)); +} + +static void +intr_eoi_src(void *arg) +{ + struct intsrc *isrc; + + isrc = arg; + isrc->is_pic->pic_eoi_source(isrc); +} + +static void +intr_disab_eoi_src(void *arg) +{ + struct intsrc *isrc; + + isrc = arg; + isrc->is_pic->pic_disable_source(isrc, PIC_EOI); +} +#else +void +intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame) +{ + struct thread *td; + struct intr_event *ie; struct intr_handler *ih; int error, vector, thread; @@ -298,6 +390,7 @@ } td->td_intr_nesting_level--; } +#endif void intr_resume(void) @@ -307,12 +400,12 @@ #ifndef DEV_ATPIC atpic_reset(); #endif - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); STAILQ_FOREACH(pic, &pics, pics) { if (pic->pic_resume != NULL) pic->pic_resume(pic); } - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); } void @@ -320,12 +413,12 @@ { struct pic *pic; - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); STAILQ_FOREACH(pic, &pics, pics) { if (pic->pic_suspend != NULL) pic->pic_suspend(pic); } - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); } static void @@ -348,8 +441,8 @@ { char straystr[MAXCOMLEN + 1]; - /* mtx_assert(&intr_table_lock, MA_OWNED); */ KASSERT(is->is_event != NULL, ("%s: isrc with no event", __func__)); + mtx_lock_spin(&intrcnt_lock); is->is_index = intrcnt_index; intrcnt_index += 2; snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", @@ -358,17 +451,18 @@ is->is_count = &intrcnt[is->is_index]; intrcnt_setname(straystr, is->is_index + 1); is->is_straycount = &intrcnt[is->is_index + 1]; + mtx_unlock_spin(&intrcnt_lock); } void intrcnt_add(const char *name, u_long **countp) { - mtx_lock_spin(&intr_table_lock); + mtx_lock_spin(&intrcnt_lock); *countp = &intrcnt[intrcnt_index]; intrcnt_setname(name, intrcnt_index); intrcnt_index++; - mtx_unlock_spin(&intr_table_lock); + mtx_unlock_spin(&intrcnt_lock); } static void @@ -378,7 +472,8 @@ intrcnt_setname("???", 0); intrcnt_index = 1; STAILQ_INIT(&pics); - mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN); + sx_init(&intr_table_lock, "intr sources"); + mtx_init(&intrcnt_lock, "intrcnt", NULL, MTX_SPIN); } SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL) @@ -486,14 +581,14 @@ return; /* Round-robin assign a CPU to each enabled source. */ - mtx_lock_spin(&intr_table_lock); + sx_xlock(&intr_table_lock); assign_cpu = 1; for (i = 0; i < NUM_IO_INTS; i++) { isrc = interrupt_sources[i]; - if (isrc != NULL && isrc->is_enabled) + if (isrc != NULL && isrc->is_handlers > 0) intr_assign_next_cpu(isrc); } - mtx_unlock_spin(&intr_table_lock); + sx_xunlock(&intr_table_lock); } SYSINIT(intr_shuffle_irqs, SI_SUB_SMP, SI_ORDER_SECOND, intr_shuffle_irqs, NULL) #endif ==== //depot/projects/smpng/sys/amd64/amd64/io_apic.c#21 (text+ko) ==== @@ -28,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/io_apic.c,v 1.29 2007/03/20 21:53:30 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/io_apic.c,v 1.30 2007/05/08 21:29:12 jhb Exp $"); #include "opt_isa.h" @@ -114,6 +114,7 @@ static void ioapic_disable_source(struct intsrc *isrc, int eoi); static void ioapic_eoi_source(struct intsrc *isrc); static void ioapic_enable_intr(struct intsrc *isrc); +static void ioapic_disable_intr(struct intsrc *isrc); static int ioapic_vector(struct intsrc *isrc); static int ioapic_source_pending(struct intsrc *isrc); static int ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig, @@ -125,8 +126,8 @@ static STAILQ_HEAD(,ioapic) ioapic_list = STAILQ_HEAD_INITIALIZER(ioapic_list); struct pic ioapic_template = { ioapic_enable_source, ioapic_disable_source, ioapic_eoi_source, ioapic_enable_intr, - ioapic_vector, ioapic_source_pending, - NULL, ioapic_resume, + ioapic_disable_intr, ioapic_vector, + ioapic_source_pending, NULL, ioapic_resume, ioapic_config_intr, ioapic_assign_cpu }; static int next_ioapic_base; @@ -359,6 +360,23 @@ } } +static void +ioapic_disable_intr(struct intsrc *isrc) +{ + struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; + u_int vector; + + if (intpin->io_vector != 0) { + /* Mask this interrupt pin and free its APIC vector. */ + vector = intpin->io_vector; + apic_disable_vector(vector); + intpin->io_masked = 1; + intpin->io_vector = 0; + ioapic_program_intpin(intpin); + apic_free_vector(vector, intpin->io_irq); + } +} + static int ioapic_vector(struct intsrc *isrc) { ==== //depot/projects/smpng/sys/amd64/amd64/local_apic.c#30 (text+ko) ==== @@ -32,7 +32,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/local_apic.c,v 1.38 2007/04/25 19:58:41 ariff Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/local_apic.c,v 1.40 2007/05/08 22:01:02 jhb Exp $"); #include "opt_hwpmc_hooks.h" @@ -65,13 +65,6 @@ #include #endif -/* - * We can handle up to 60 APICs via our logical cluster IDs, but currently - * the physical IDs on Intel processors up to the Pentium 4 are limited to - * 16. - */ -#define MAX_APICID 16 - /* Sanity checks on IDT vectors. */ CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS == APIC_TIMER_INT); CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS); @@ -114,7 +107,7 @@ u_long la_hard_ticks; u_long la_stat_ticks; u_long la_prof_ticks; -} static lapics[MAX_APICID]; +} static lapics[MAX_APIC_ID + 1]; /* XXX: should thermal be an NMI? */ @@ -147,6 +140,8 @@ APIC_TDCR_32, APIC_TDCR_64, APIC_TDCR_128 }; +extern inthand_t IDTVEC(rsvd); + volatile lapic_t *lapic; vm_paddr_t lapic_paddr; static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz; @@ -238,7 +233,7 @@ { int i; - if (apic_id >= MAX_APICID) { + if (apic_id > MAX_APIC_ID) { printf("APIC: Ignoring local APIC with ID %d\n", apic_id); if (boot_cpu) panic("Can't ignore BSP"); @@ -837,6 +832,16 @@ setidt(vector, ioint_handlers[vector / 32], SDT_SYSIGT, SEL_KPL, 0); } +void +apic_disable_vector(u_int vector) +{ + + KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry")); + KASSERT(ioint_handlers[vector / 32] != NULL, + ("No ISR handler for vector %u", vector)); + setidt(vector, &IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0); +} + /* Release an APIC vector when it's no longer in use. */ void apic_free_vector(u_int vector, u_int irq) ==== //depot/projects/smpng/sys/amd64/amd64/mp_machdep.c#42 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.283 2007/03/06 17:16:46 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.284 2007/05/08 22:01:02 jhb Exp $"); #include "opt_cpu.h" #include "opt_kstack_pages.h" @@ -151,7 +151,7 @@ int cpu_present:1; int cpu_bsp:1; int cpu_disabled:1; -} static cpu_info[MAXCPU]; +} static cpu_info[MAX_APIC_ID + 1]; int cpu_apic_ids[MAXCPU]; /* Holds pending bitmap based IPIs per CPU */ @@ -159,6 +159,7 @@ static u_int boot_address; +static void assign_cpu_ids(void); static void set_interrupt_apic_ids(void); static int start_all_aps(void); static int start_ap(int apic_id); @@ -204,7 +205,7 @@ } group = &mp_groups[0]; groups = 1; - for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) { + for (cpu = 0, apic_id = 0; apic_id <= MAX_APIC_ID; apic_id++) { if (!cpu_info[apic_id].cpu_present) continue; /* @@ -246,9 +247,8 @@ cpu_add(u_int apic_id, char boot_cpu) { - if (apic_id >= MAXCPU) { - printf("SMP: CPU %d exceeds maximum CPU %d, ignoring\n", - apic_id, MAXCPU - 1); + if (apic_id > MAX_APIC_ID) { + panic("SMP: APIC ID %d too high", apic_id); return; } KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice", @@ -261,13 +261,13 @@ boot_cpu_id = apic_id; cpu_info[apic_id].cpu_bsp = 1; } - mp_ncpus++; - if (apic_id > mp_maxid) - mp_maxid = apic_id; + if (mp_ncpus < MAXCPU) { + mp_ncpus++; + mp_maxid = mp_ncpus -1; + } if (bootverbose) printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" : "AP"); - } void @@ -286,8 +286,7 @@ else KASSERT(mp_maxid >= mp_ncpus - 1, ("%s: counters out of sync: max %d, count %d", __func__, - mp_maxid, mp_ncpus)); - + mp_maxid, mp_ncpus)); } int @@ -365,6 +364,8 @@ ("BSP's APIC ID doesn't match boot_cpu_id")); cpu_apic_ids[0] = boot_cpu_id; + assign_cpu_ids(); + /* Start each Application Processor */ start_all_aps(); @@ -429,7 +430,7 @@ /* List CPUs */ printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id); - for (i = 1, x = 0; x < MAXCPU; x++) { + for (i = 1, x = 0; x <= MAX_APIC_ID; x++) { if (!cpu_info[x].cpu_present || cpu_info[x].cpu_bsp) continue; if (cpu_info[x].cpu_disabled) @@ -646,6 +647,48 @@ } /* + * Assign logical CPU IDs to local APICs. + */ +static void +assign_cpu_ids(void) +{ + u_int i; + + /* Check for explicitly disabled CPUs. */ + for (i = 0; i <= MAX_APIC_ID; i++) { + if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp) + continue; + + /* Don't use this CPU if it has been disabled by a tunable. */ + if (resource_disabled("lapic", i)) { + cpu_info[i].cpu_disabled = 1; + continue; + } + } + + /* + * Assign CPU IDs to local APIC IDs and disable any CPUs + * beyond MAXCPU. CPU 0 has already been assigned to the BSP, + * so we only have to assign IDs for APs. + */ + mp_ncpus = 1; + for (i = 0; i <= MAX_APIC_ID; i++) { + if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp || + cpu_info[i].cpu_disabled) + continue; + + if (mp_ncpus < MAXCPU) { + cpu_apic_ids[mp_ncpus] = i; + mp_ncpus++; + } else + cpu_info[i].cpu_disabled = 1; + } + KASSERT(mp_maxid >= mp_ncpus - 1, + ("%s: counters out of sync: max %d, count %d", __func__, mp_maxid, + mp_ncpus)); +} + +/* * start each AP in our list */ static int @@ -696,24 +739,8 @@ outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ /* start each AP */ - for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) { - - /* Ignore non-existent CPUs and the BSP. */ - if (!cpu_info[apic_id].cpu_present || - cpu_info[apic_id].cpu_bsp) - continue; - - /* Don't use this CPU if it has been disabled by a tunable. */ - if (resource_disabled("lapic", apic_id)) { - cpu_info[apic_id].cpu_disabled = 1; - mp_ncpus--; - continue; - } - - cpu++; - - /* save APIC ID for this logical ID */ - cpu_apic_ids[cpu] = apic_id; + for (cpu = 1; cpu < mp_ncpus; cpu++) { + apic_id = cpu_apic_ids[cpu]; /* allocate and set up an idle stack data page */ bootstacks[cpu] = (void *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); ==== //depot/projects/smpng/sys/amd64/amd64/mptable.c#12 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable.c,v 1.239 2007/03/09 15:49:57 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable.c,v 1.240 2007/05/08 22:01:02 jhb Exp $"); #include #include @@ -50,7 +50,7 @@ /* string defined by the Intel MP Spec as identifying the MP table */ #define MP_SIG 0x5f504d5f /* _MP_ */ -#define NAPICID 32 /* Max number of APIC's */ +#define MAX_LAPIC_ID 63 /* Max local APIC ID for HTT fixup */ #define BIOS_BASE (0xf0000) #define BIOS_SIZE (0x10000) @@ -136,7 +136,7 @@ static mpfps_t mpfps; static mpcth_t mpct; -static void *ioapics[NAPICID]; +static void *ioapics[MAX_APIC_ID + 1]; static bus_datum *busses; static int mptable_nioapics, mptable_nbusses, mptable_maxbusid; static int pci0 = -1; @@ -152,7 +152,7 @@ static void mptable_count_items(void); static void mptable_count_items_handler(u_char *entry, void *arg); #ifdef MPTABLE_FORCE_HTT -static void mptable_hyperthread_fixup(u_int id_mask); +static void mptable_hyperthread_fixup(u_long id_mask); #endif static void mptable_parse_apics_and_busses(void); static void mptable_parse_apics_and_busses_handler(u_char *entry, @@ -294,7 +294,7 @@ static int mptable_probe_cpus(void) { - u_int cpu_mask; + u_long cpu_mask; /* Is this a pre-defined config? */ if (mpfps->config_type != 0) { @@ -356,7 +356,7 @@ mptable_parse_ints(); /* Fourth, we register all the I/O APIC's. */ - for (i = 0; i < NAPICID; i++) + for (i = 0; i <= MAX_APIC_ID; i++) if (ioapics[i] != NULL) ioapic_register(ioapics[i]); @@ -414,7 +414,7 @@ mptable_probe_cpus_handler(u_char *entry, void *arg) { proc_entry_ptr proc; - u_int *cpu_mask; + u_long *cpu_mask; switch (*entry) { case MPCT_ENTRY_PROCESSOR: @@ -422,8 +422,10 @@ if (proc->cpu_flags & PROCENTRY_FLAG_EN) { lapic_create(proc->apic_id, proc->cpu_flags & PROCENTRY_FLAG_BP); - cpu_mask = (u_int *)arg; - *cpu_mask |= (1 << proc->apic_id); + if (proc->apic_id < MAX_LAPIC_ID) { + cpu_mask = (u_long *)arg; + *cpu_mask |= (1ul << proc->apic_id); + } } break; } @@ -510,7 +512,7 @@ apic = (io_apic_entry_ptr)entry; if (!(apic->apic_flags & IOAPICENTRY_FLAG_EN)) break; - if (apic->apic_id >= NAPICID) + if (apic->apic_id > MAX_APIC_ID) panic("%s: I/O APIC ID %d too high", __func__, apic->apic_id); if (ioapics[apic->apic_id] != NULL) @@ -655,7 +657,7 @@ return; } } - if (apic_id >= NAPICID) { + if (apic_id > MAX_APIC_ID) { printf("MPTable: Ignoring interrupt entry for ioapic%d\n", intr->dst_apic_id); return; @@ -868,7 +870,7 @@ * with the number of logical CPU's in the processor. */ static void -mptable_hyperthread_fixup(u_int id_mask) +mptable_hyperthread_fixup(u_long id_mask) { u_int i, id, logical_cpus; @@ -885,7 +887,7 @@ * physical processor. If any of those ID's are * already in the table, then kill the fixup. */ - for (id = 0; id < NAPICID; id++) { + for (id = 0; id <= MAX_LAPIC_ID; id++) { if ((id_mask & 1 << id) == 0) continue; /* First, make sure we are on a logical_cpus boundary. */ @@ -900,7 +902,7 @@ * Ok, the ID's checked out, so perform the fixup by * adding the logical CPUs. */ - while ((id = ffs(id_mask)) != 0) { + while ((id = ffsl(id_mask)) != 0) { id--; for (i = id + 1; i < id + logical_cpus; i++) { if (bootverbose) ==== //depot/projects/smpng/sys/amd64/amd64/msi.c#6 (text+ko) ==== @@ -34,7 +34,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/amd64/amd64/msi.c,v 1.5 2007/05/02 17:50:34 jhb Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/msi.c,v 1.6 2007/05/08 21:29:13 jhb Exp $"); #include #include >>> TRUNCATED FOR MAIL (1000 lines) <<<