Date: Sun, 22 Mar 2009 10:33:10 +0000 (UTC) From: Marius Strobl <marius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r190257 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb sparc64/include sparc64/sparc64 Message-ID: <200903221033.n2MAXBme066193@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: marius Date: Sun Mar 22 10:33:10 2009 New Revision: 190257 URL: http://svn.freebsd.org/changeset/base/190257 Log: MFC: r183142, r186395, 190106 - Newer firmware versions no longer provide SUNW,stop-self so just disable interrupts and loop forever instead. We still could use SUNW,stop-self if implemented but acording to comments in OpenBSD, E{2,4}50 tend to have fragile firmware versions which wedge when using the OFW test service, so given that we don't really depend on SUNW,stop-self just nuke it altogether instead of risking problems. - Hide all MP-related bits in <machine/smp.h> underneath #ifdef SMP. - Inline ipi_all_but_self(9) and ipi_selected(9). We don't expose any additional bits but save a few cycles by doing so. - Remove ipi_all(9), which actually only called panic(9). It can't be implemented natively anyway and having it removed at least causes MI users to already fail when linking. - At least Fire V880 have a small hardware glitch which causes the reception of IDR_NACKs for CPUs we actually haven't tried to send an IPI to, even not as part of the initial try. According to tests this apparently can be safely ignored though, so just return if checking for the individual IDR_NACKs indicates no outstanding dispatch. Serializing the sending of IPIs between MD and MI code by the combined usage of smp_ipi_mtx makes no difference to this phenomenon. [1] - Provide relevant debugging bits already with the initial panic in case of problems with the IPI dispatch, which would have allowed to diagnose the above problem without a specially built kernel. - In case of cheetah_ipi_selected() base the delay we wait for other CPUs which also might want to dispatch IPIs on the total amount of CPUs instead of just the number of CPUs we let this CPU send IPIs to because in the worst case all CPUs also want to IPI us at the same time. - There's no need to wrap kdb_active in #ifdef KDB as it's always available. Reported and access for extensive tests provided by: beat [1] Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) stable/7/sys/sparc64/include/smp.h stable/7/sys/sparc64/sparc64/genassym.c stable/7/sys/sparc64/sparc64/mp_machdep.c Modified: stable/7/sys/sparc64/include/smp.h ============================================================================== --- stable/7/sys/sparc64/include/smp.h Sun Mar 22 10:08:41 2009 (r190256) +++ stable/7/sys/sparc64/include/smp.h Sun Mar 22 10:33:10 2009 (r190257) @@ -29,6 +29,8 @@ #ifndef _MACHINE_SMP_H_ #define _MACHINE_SMP_H_ +#ifdef SMP + #define CPU_TICKSYNC 1 #define CPU_STICKSYNC 2 #define CPU_INIT 3 @@ -91,10 +93,6 @@ void cpu_mp_shutdown(void); typedef void cpu_ipi_selected_t(u_int, u_long, u_long, u_long); extern cpu_ipi_selected_t *cpu_ipi_selected; -void ipi_selected(u_int cpus, u_int ipi); -void ipi_all(u_int ipi); -void ipi_all_but_self(u_int ipi); - void mp_init(void); extern struct mtx ipi_mtx; @@ -117,7 +115,19 @@ extern char tl_ipi_tlb_context_demap[]; extern char tl_ipi_tlb_page_demap[]; extern char tl_ipi_tlb_range_demap[]; -#ifdef SMP +static __inline void +ipi_all_but_self(u_int ipi) +{ + + cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi); +} + +static __inline void +ipi_selected(u_int cpus, u_int ipi) +{ + + cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi); +} #if defined(_MACHINE_PMAP_H_) && defined(_SYS_MUTEX_H_) @@ -224,8 +234,12 @@ ipi_wait(void *cookie) #endif /* _MACHINE_PMAP_H_ && _SYS_MUTEX_H_ */ +#endif /* !LOCORE */ + #else +#ifndef LOCORE + static __inline void * ipi_dcache_page_inval(void *func, vm_paddr_t pa) { @@ -267,8 +281,26 @@ ipi_wait(void *cookie) } -#endif /* SMP */ +static __inline void +tl_ipi_cheetah_dcache_page_inval(void) +{ + +} + +static __inline void +tl_ipi_spitfire_dcache_page_inval(void) +{ + +} + +static __inline void +tl_ipi_spitfire_icache_page_inval(void) +{ + +} #endif /* !LOCORE */ +#endif /* SMP */ + #endif /* !_MACHINE_SMP_H_ */ Modified: stable/7/sys/sparc64/sparc64/genassym.c ============================================================================== --- stable/7/sys/sparc64/sparc64/genassym.c Sun Mar 22 10:08:41 2009 (r190256) +++ stable/7/sys/sparc64/sparc64/genassym.c Sun Mar 22 10:33:10 2009 (r190257) @@ -83,6 +83,7 @@ ASSYM(PAGE_SHIFT_4M, PAGE_SHIFT_4M); ASSYM(PAGE_SIZE, PAGE_SIZE); ASSYM(PAGE_SIZE_4M, PAGE_SIZE_4M); +#ifdef SMP ASSYM(CSA_PCPU, offsetof(struct cpu_start_args, csa_pcpu)); ASSYM(CSA_STATE, offsetof(struct cpu_start_args, csa_state)); #ifdef SUN4U @@ -95,6 +96,7 @@ ASSYM(CSA_VER, offsetof(struct cpu_start #ifdef SUN4V ASSYM(CSA_CPUID, offsetof(struct cpu_start_args, csa_cpuid)); #endif +#endif #ifdef SUN4U ASSYM(DC_SIZE, offsetof(struct cacheinfo, dc_size)); @@ -103,7 +105,9 @@ ASSYM(IC_SIZE, offsetof(struct cacheinfo ASSYM(IC_LINESIZE, offsetof(struct cacheinfo, ic_linesize)); #endif +#ifdef SMP ASSYM(ICA_PA, offsetof(struct ipi_cache_args, ica_pa)); +#endif ASSYM(KTR_SIZEOF, sizeof(struct ktr_entry)); ASSYM(KTR_LINE, offsetof(struct ktr_entry, ktr_line)); @@ -210,11 +214,13 @@ ASSYM(IR_ARG, offsetof(struct intr_reque ASSYM(IR_PRI, offsetof(struct intr_request, ir_pri)); ASSYM(IR_VEC, offsetof(struct intr_request, ir_vec)); +#ifdef SMP ASSYM(ITA_MASK, offsetof(struct ipi_tlb_args, ita_mask)); ASSYM(ITA_PMAP, offsetof(struct ipi_tlb_args, ita_pmap)); ASSYM(ITA_START, offsetof(struct ipi_tlb_args, ita_start)); ASSYM(ITA_END, offsetof(struct ipi_tlb_args, ita_end)); ASSYM(ITA_VA, offsetof(struct ipi_tlb_args, ita_va)); +#endif ASSYM(IV_FUNC, offsetof(struct intr_vector, iv_func)); ASSYM(IV_ARG, offsetof(struct intr_vector, iv_arg)); Modified: stable/7/sys/sparc64/sparc64/mp_machdep.c ============================================================================== --- stable/7/sys/sparc64/sparc64/mp_machdep.c Sun Mar 22 10:08:41 2009 (r190256) +++ stable/7/sys/sparc64/sparc64/mp_machdep.c Sun Mar 22 10:33:10 2009 (r190257) @@ -92,6 +92,9 @@ __FBSDID("$FreeBSD$"); #include <machine/tte.h> #include <machine/ver.h> +#define SUNW_STARTCPU "SUNW,start-cpu" +#define SUNW_STOPSELF "SUNW,stop-self" + static ih_func_t cpu_ipi_ast; static ih_func_t cpu_ipi_preempt; static ih_func_t cpu_ipi_stop; @@ -119,7 +122,6 @@ static volatile u_int shutdown_cpus; static void cpu_mp_unleash(void *v); static void spitfire_ipi_send(u_int mid, u_long d0, u_long d1, u_long d2); static void sun4u_startcpu(phandle_t cpu, void *func, u_long arg); -static void sun4u_stopself(void); static cpu_ipi_selected_t cheetah_ipi_selected; static cpu_ipi_selected_t spitfire_ipi_selected; @@ -203,7 +205,7 @@ sun4u_startcpu(phandle_t cpu, void *func cell_t func; cell_t arg; } args = { - (cell_t)"SUNW,start-cpu", + (cell_t)SUNW_STARTCPU, 3, }; @@ -214,24 +216,6 @@ sun4u_startcpu(phandle_t cpu, void *func } /* - * Stop the calling CPU. - */ -static void -sun4u_stopself(void) -{ - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - } args = { - (cell_t)"SUNW,stop-self", - }; - - openfirmware_exit(&args); - panic("%s: failed.", __func__); -} - -/* * Fire up any non-boot processors. */ void @@ -422,8 +406,6 @@ cpu_mp_shutdown(void) break; } } - /* XXX: delay a bit to allow the CPUs to actually enter the PROM. */ - DELAY(100000); critical_exit(); } @@ -443,7 +425,9 @@ cpu_ipi_stop(struct trapframe *tf) while ((started_cpus & PCPU_GET(cpumask)) == 0) { if ((shutdown_cpus & PCPU_GET(cpumask)) != 0) { atomic_clear_int(&shutdown_cpus, PCPU_GET(cpumask)); - sun4u_stopself(); + (void)intr_disable(); + for (;;) + ; } } atomic_clear_rel_int(&started_cpus, PCPU_GET(cpumask)); @@ -519,15 +503,12 @@ spitfire_ipi_send(u_int mid, u_long d0, */ DELAY(2); } - if ( -#ifdef KDB - kdb_active || -#endif - panicstr != NULL) + if (kdb_active != 0 || panicstr != NULL) printf("%s: couldn't send IPI to module 0x%u\n", __func__, mid); else - panic("%s: couldn't send IPI", __func__); + panic("%s: couldn't send IPI to module 0x%u", + __func__, mid); } static void @@ -581,40 +562,23 @@ cheetah_ipi_selected(u_int cpus, u_long } } /* + * On at least Fire V880 we may receive IDR_NACKs for + * CPUs we actually haven't tried to send an IPI to, + * but which apparently can be safely ignored. + */ + if (cpus == 0) + return; + /* * Leave interrupts enabled for a bit before retrying * in order to avoid deadlocks if the other CPUs are * also trying to send IPIs. */ - DELAY(2 * bnp); + DELAY(2 * mp_ncpus); } - if ( -#ifdef KDB - kdb_active || -#endif - panicstr != NULL) + if (kdb_active != 0 || panicstr != NULL) printf("%s: couldn't send IPI (cpus=0x%u ids=0x%lu)\n", __func__, cpus, ids); else - panic("%s: couldn't send IPI", __func__); -} - -void -ipi_selected(u_int cpus, u_int ipi) -{ - - cpu_ipi_selected(cpus, 0, (u_long)tl_ipi_level, ipi); -} - -void -ipi_all(u_int ipi) -{ - - panic("%s", __func__); -} - -void -ipi_all_but_self(u_int ipi) -{ - - cpu_ipi_selected(PCPU_GET(other_cpus), 0, (u_long)tl_ipi_level, ipi); + panic("%s: couldn't send IPI (cpus=0x%u ids=0x%lu)", + __func__, cpus, ids); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903221033.n2MAXBme066193>