From 3360c3ea247d208e9a9565c7a016db5fe924716f Mon Sep 17 00:00:00 2001 From: Joe Talbott Date: Thu, 28 Jun 2007 16:30:36 -0400 Subject: [PATCH] Start flushing out the IPI routines and do some clean-up. Added IPI signal handler from Aggelos Economopoulos. Removed a bunch of old debug kprintf()s and #if 0'ed out code. --- sys/kern/lwkt_ipiq.c | 2 +- sys/kern/lwkt_thread.c | 4 + sys/kern/uipc_domain.c | 14 +++ sys/netproto/ipsec/key.c | 1 + sys/netproto/ipsec/keysock.c | 2 + sys/netproto/key/key.c | 1 + sys/platform/vkernel/i386/autoconf.c | 27 +++-- sys/platform/vkernel/i386/cpu_regs.c | 2 + sys/platform/vkernel/i386/exception.c | 23 ++++ sys/platform/vkernel/i386/mp.c | 214 ++++++++++------------------------ 10 files changed, 131 insertions(+), 159 deletions(-) diff --git a/sys/kern/lwkt_ipiq.c b/sys/kern/lwkt_ipiq.c index c8509af736..f522cedb51 100644 --- a/sys/kern/lwkt_ipiq.c +++ b/sys/kern/lwkt_ipiq.c @@ -453,7 +453,7 @@ again: sgd = globaldata_find(n); ip = sgd->gd_ipiq; if (ip != NULL) { - while (lwkt_process_ipiq_core(sgd, &ip[gd->gd_cpuid], NULL)) + while (lwkt_process_ipiq_core(sgd, &ip[gd->gd_cpuid], NULL)) ; } } diff --git a/sys/kern/lwkt_thread.c b/sys/kern/lwkt_thread.c index 4287663bee..2fbb65e1fa 100644 --- a/sys/kern/lwkt_thread.c +++ b/sys/kern/lwkt_thread.c @@ -1292,9 +1292,13 @@ lwkt_create(void (*func)(void *), void *arg, * Schedule the thread to run */ if ((td->td_flags & TDF_STOPREQ) == 0) + { lwkt_schedule(td); + } else + { td->td_flags &= ~TDF_STOPREQ; + } return 0; } diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index e78596ee4b..0cd73c53f4 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -82,22 +82,34 @@ net_init_domain(struct domain *dp) { struct protosw *pr; + kprintf("net_init_domain: 1\n"); crit_enter(); + kprintf("net_init_domain: 2\n"); if (dp->dom_init) + { + kprintf("net_init_domain: 3\n"); (*dp->dom_init)(); + } for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { + kprintf("net_init_domain: 4\n"); if (pr->pr_usrreqs == NULL) panic("domaininit: %ssw[%d] has no usrreqs!", dp->dom_name, pr - dp->dom_protosw); if (pr->pr_init) + { + kprintf("net_init_domain: 5 pr->pr_init: %p\n", + pr->pr_init); (*pr->pr_init)(); + } } /* * update global information about maximums */ max_hdr = max_linkhdr + max_protohdr; max_datalen = MHLEN - max_hdr; + kprintf("net_init_domain: 6\n"); crit_exit(); + kprintf("net_init_domain: 7\n"); } /* @@ -113,7 +125,9 @@ net_add_domain(void *data) crit_enter(); SLIST_INSERT_HEAD(&domains, dp, dom_next); crit_exit(); + kprintf("XXX in net_add_domain\n"); net_init_domain(dp); + kprintf("XXX in net_add_domain after net_init_domain\n"); } /* ARGSUSED*/ diff --git a/sys/netproto/ipsec/key.c b/sys/netproto/ipsec/key.c index a6fc2cf6f0..6baded1e85 100644 --- a/sys/netproto/ipsec/key.c +++ b/sys/netproto/ipsec/key.c @@ -6759,6 +6759,7 @@ key_init(void) keystat.getspi_count = 1; kprintf("IPsec: Initialized Security Association Processing.\n"); + kprintf("XXX 1\n"); return; } diff --git a/sys/netproto/ipsec/keysock.c b/sys/netproto/ipsec/keysock.c index 5fb793767d..3ca80a7930 100644 --- a/sys/netproto/ipsec/keysock.c +++ b/sys/netproto/ipsec/keysock.c @@ -577,7 +577,9 @@ static void key_init0(void) { bzero((caddr_t)&key_cb, sizeof(key_cb)); + kprintf("XXX in key_init0()\n"); key_init(); + kprintf("XXX after key_init()\n"); } struct domain keydomain = { diff --git a/sys/netproto/key/key.c b/sys/netproto/key/key.c index 2e39146660..93d2379895 100644 --- a/sys/netproto/key/key.c +++ b/sys/netproto/key/key.c @@ -7112,6 +7112,7 @@ key_init(void) keystat.getspi_count = 1; kprintf("IPsec: Initialized Security Association Processing.\n"); + kprintf("XXX 2\n"); return; } diff --git a/sys/platform/vkernel/i386/autoconf.c b/sys/platform/vkernel/i386/autoconf.c index 70b3c7c2bb..1374211a53 100644 --- a/sys/platform/vkernel/i386/autoconf.c +++ b/sys/platform/vkernel/i386/autoconf.c @@ -92,6 +92,11 @@ device_t isa_bus_device = 0; #endif +#include +#include + +void ipi_handler(int); + static void cpu_startup (void *); static void configure_first (void *); static void configure (void *); @@ -117,6 +122,12 @@ SYSINIT(configure3, SI_SUB_CONFIGURE, SI_ORDER_ANY, configure_final, NULL); cdev_t rootdev = NULL; cdev_t dumpdev = NULL; +void +ipi_handler(int sig) +{ + kprintf("ipi_handler: sig = %d\n", sig); +} + /* * */ @@ -128,7 +139,14 @@ cpu_startup(void *dummy) vm_offset_t pager_sva; vm_offset_t pager_eva; - kprintf("JAT: cpu_startup() start\n"); +#if 0 + if (signal(SIGUSR1, ipi_handler) == SIG_ERR) + warn("signal failed"); + else + kprintf("signal set up\n"); +#endif + + kprintf("%s", version); kprintf("real memory = %llu (%lluK bytes)\n", ptoa(Maxmem), ptoa(Maxmem) / 1024); @@ -187,7 +205,6 @@ cpu_startup(void *dummy) mp_announce(); #endif cpu_setregs(); - kprintf("JAT: cpu_startup() end\n"); } /* @@ -201,7 +218,6 @@ configure_first(void *dummy) static void configure(void *dummy) { - kprintf("JAT: configure() start\n"); /* * Final interrupt support acviation, then enable hardware interrupts. */ @@ -233,18 +249,15 @@ configure(void *dummy) * at splhigh()), but we want at least bio interrupts to work. */ safepri = TDPRI_KERN_USER; - kprintf("JAT: configure() end\n"); } static void configure_final(void *dummy) { - kprintf("JAT: configure_final() start\n"); cninit_finish(); if (bootverbose) kprintf("Device configuration finished.\n"); - kprintf("JAT: configure_final() end\n"); } #ifdef BOOTP @@ -256,7 +269,6 @@ void bootpc_init(void); void cpu_rootconf(void) { - kprintf("JAT: cpu_rootconf() start\n"); #ifdef BOOTP bootpc_init(); #endif @@ -271,7 +283,6 @@ cpu_rootconf(void) if (!rootdevnames[0]) setroot(); #endif - kprintf("JAT: cpu_rootconf() end\n"); } SYSINIT(cpu_rootconf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, cpu_rootconf, NULL) diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c index 2fa15087a2..e3007bcd67 100644 --- a/sys/platform/vkernel/i386/cpu_regs.c +++ b/sys/platform/vkernel/i386/cpu_regs.c @@ -665,6 +665,8 @@ fetchupcall (struct vmupcall *vu, int morepending, void *rsp) * will be entered with the possibility that no IPI will occur and in such * cases lwkt_switch() sets TDF_IDLE_NOHLT. */ + +/* XXX since we don't have IPIs implemented don't let the CPU halt */ static int cpu_idle_hlt = 1; static int cpu_idle_hltcnt; static int cpu_idle_spincnt; diff --git a/sys/platform/vkernel/i386/exception.c b/sys/platform/vkernel/i386/exception.c index ddc9931fdf..acd941b88e 100644 --- a/sys/platform/vkernel/i386/exception.c +++ b/sys/platform/vkernel/i386/exception.c @@ -66,6 +66,26 @@ static struct kproc_desc sigshut_kp = { "sigshutdown", sigshutdown_daemon, &sigshutdown_thread }; +static +void +ipi(int nada, siginfo_t *info, void *ctxp) +{ + kprintf("ipi\n"); + if (curthread->td_pri < TDPRI_CRIT) { + kprintf("ipi pri < TDPRI_CRIT"); + ++mycpu->gd_intr_nesting_level; + curthread->td_pri += TDPRI_CRIT; + lwkt_process_ipiq(); + curthread->td_pri -= TDPRI_CRIT; + --mycpu->gd_intr_nesting_level; + } else { + kprintf("ipi pri > TDPRI_CRIT"); + mycpu->gd_reqflags |= RQF_IPIQ; + lwkt_process_ipiq(); + } +} + + void init_exceptions(void) { @@ -83,6 +103,9 @@ init_exceptions(void) sigaction(SIGQUIT, &sa, NULL); #endif + sa.sa_sigaction = ipi; + sigaction(SIGUSR1, &sa, NULL); + bzero(&sa, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_flags |= SA_MAILBOX | SA_NODEFER; diff --git a/sys/platform/vkernel/i386/mp.c b/sys/platform/vkernel/i386/mp.c index ab80a8e8b5..b41f5cbedb 100644 --- a/sys/platform/vkernel/i386/mp.c +++ b/sys/platform/vkernel/i386/mp.c @@ -55,6 +55,7 @@ #include #include +#include #include extern pt_entry_t *KPTphys; @@ -66,7 +67,11 @@ static cpumask_t smp_startup_mask = 1; /* which cpus have been started */ int mp_naps; /* # of Applications processors */ static int mp_finish; +/* function prototypes XXX these should go elsewhere */ void bootstrap_idle(void); +#if 0 +void ipi_handler(int); +#endif pt_entry_t *SMPpt; @@ -80,10 +85,6 @@ static int start_all_aps(u_int); void init_secondary(void); void *start_ap(void *); -#if 0 -u_int mp_lock; -#endif - /* * Get SMP fully working before we start initializing devices. */ @@ -101,21 +102,11 @@ ap_finish(void) if (bootverbose) kprintf("Finish MP startup\n"); - kprintf("ap_finish: mycpu->gd_cpuid = %d\n", mycpu->gd_cpuid); rel_mplock(); - printf("smp_active_mask: %d, smp_startup_mask: %d, ncpus_mask: %d\n", - smp_active_mask, smp_startup_mask, ncpus_mask); - printf("ncpus2_mask: %d, ncpus_fit_mask: %d\n", - ncpus2_mask, ncpus_fit_mask); - while (smp_active_mask != smp_startup_mask) { -/* - kprintf("smp_active_mask: %d, smp_startup_mask: %d\n", - smp_active_mask, smp_startup_mask); -*/ + + while (smp_active_mask != smp_startup_mask) cpu_lfence(); - } - printf("smp_active_mask: %d, smp_startup_mask: %d, ncpus_mask: %d\n", - smp_active_mask, smp_startup_mask, ncpus_mask); + while (try_mplock() == 0) ; if (bootverbose) @@ -129,23 +120,9 @@ void * start_ap(void *arg) { int ap_id = *(int *)arg; - kprintf("mycpu->gd_cpuid: %d\n", mycpu->gd_cpuid); init_secondary(); -/* - get_mplock(); - while (try_mplock() == 0) - ; - - rel_mplock(); -*/ - kprintf("mycpu->gd_cpuid: %d\n", mycpu->gd_cpuid); - kprintf("start_ap %d\n", ap_id); -/* - while (try_mplock() == 0) - ; -*/ bootstrap_idle(); return(NULL); /* NOTREACHED */ @@ -153,9 +130,6 @@ start_ap(void *arg) /* storage for AP thread IDs */ pthread_t ap_tids[MAXCPU]; -#if 0 -lwpid_t ap_tids[MAXCPU]; -#endif void mp_start(void) @@ -206,8 +180,12 @@ forward_fastint_remote(void *arg) void cpu_send_ipiq(int dcpu) { - kprintf("cpu_send_ipiq(%d)\n", dcpu); + kprintf("cpu_send_ipiq(%d), smp_active_mask = %x\n", dcpu, smp_active_mask); + if ((1 << dcpu) & smp_active_mask) + pthread_kill(ap_tids[dcpu], SIGUSR1); +#if 0 panic("XXX cpu_send_ipiq()"); +#endif } void @@ -218,9 +196,30 @@ smp_invltlb(void) #endif } +void +single_cpu_ipi(int cpu, int vector, int delivery_mode) +{ + kprintf("XXX single_cpu_ipi\n"); +} + +void +selected_cpu_ipi(u_int target, int vector, int delivery_mode) +{ + crit_enter(); + while (target) { + int n = bsfl(target); + target &= ~(1 << n); + single_cpu_ipi(n, vector, delivery_mode); + } + crit_exit(); +} + int stop_cpus(u_int map) { + map &= smp_active_mask; + + panic("XXX stop_cpus()"); } @@ -243,7 +242,6 @@ ap_init(void) * trying to send us an IPI. */ - kprintf("ap_init()\n"); smp_startup_mask |= 1 << mycpu->gd_cpuid; cpu_mfence(); @@ -263,14 +261,10 @@ ap_init(void) * caching it. */ - kprintf("mp_finish: %d\n", mp_finish); while (mp_finish == 0) { - /* printf("mp_finish (loop): %d\n", mp_finish); */ cpu_lfence(); } - printf("mp_finish: %d\n", mp_finish); ++curthread->td_mpcount; - kprintf("td_mpcount: %d\n", curthread->td_mpcount); while (cpu_try_mplock() == 0) ; @@ -302,6 +296,11 @@ ap_init(void) KKASSERT(curthread->td_mpcount == 1); smp_active_mask |= 1 << mycpu->gd_cpuid; + mdcpu->gd_fpending = 0; + mdcpu->gd_ipending = 0; + initclocks_pcpu(); /* clock interrupts (via IPIs) */ + lwkt_process_ipiq(); + /* * Releasing the mp lock lets the BSP finish up the SMP init */ @@ -318,11 +317,6 @@ init_secondary(void) ps = &CPU_prvspace[myid]; -#if 0 - gdt_segs[GPRIV_SEL].ssd_base = (int)ps; - gdt_segs[GPROC0_SEL].ssd_base = - (int) &ps->mdglobaldata.gd_common_tss; -#endif ps->mdglobaldata.mi.gd_prvspace = ps; /* @@ -331,62 +325,35 @@ init_secondary(void) */ tls_set_fs(&CPU_prvspace[myid], sizeof(struct privatespace)); -#if 0 - for (x = 0; x < NGDT; x++) { - ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd); - } - - r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; - r_gdt.rd_base = (int) &gdt[myid * NGDT]; - lgdt(&r_gdt); /* does magic intra-segment return */ - - lidt(&r_idt); - - lldt(_default_ldt); - mdcpu->gd_currentldt = _default_ldt; - - gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); - gdt[myid * NGDT + GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; - -#endif md = mdcpu; /* loaded through %fs:0 (mdglobaldata.mi.gd_prvspace)*/ md->gd_common_tss.tss_esp0 = 0; /* not used until after switch */ md->gd_common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); md->gd_common_tss.tss_ioopt = (sizeof md->gd_common_tss) << 16; -#if 0 - md->gd_tss_gdt = &gdt[myid * NGDT + GPROC0_SEL].sd; - md->gd_common_tssd = *md->gd_tss_gdt; - ltr(gsel_tss); -#endif /* * Set to a known state: * Set by mpboot.s: CR0_PG, CR0_PE * Set by cpu_setregs: CR0_NE, CR0_MP, CR0_TS, CR0_WP, CR0_AM */ -#if 0 - cr0 = rcr0(); - cr0 &= ~(CR0_CD | CR0_NW | CR0_EM); - load_cr0(cr0); - pmap_set_opt(); /* PSE/4MB pages, etc */ - - /* set up CPU registers and state */ - cpu_setregs(); +} - /* set up FPU state on the AP */ - npxinit(__INITIAL_NPXCW__); +#if 0 +void +ipi_handler(int sig) +{ + kprintf("processing IPI queue, sig: %d\n", sig); - /* set up SSE registers */ - enable_sse(); -#endif + if (sig == SIGUSR1) { + kprintf("processing IPI queue\n"); + } } - +#endif static int start_all_aps(u_int boot_addr) { - int x, i, count; + int x, i; int *arg; struct mdglobaldata *gd; struct privatespace *ps; @@ -394,21 +361,30 @@ start_all_aps(u_int boot_addr) vm_offset_t va; struct lwp_params params; +#if 0 + /* set up a signal handler to handle IPIs */ + signal(SIGUSR1, ipi_handler); +#endif + /* store the mappings so we can populate gd_CMAP[0-2] and gd_PMAP3 */ vpte_t *SMPpt2[4]; + /* + * needed for ipis to initial thread + * FIXME: rename ap_tids? + */ + ap_tids[0] = pthread_self(); + for (x = 1; x <= mp_naps; x++) { - count = 0; - /* Allocate space for the CPU's private space. */ va = (vm_offset_t)&CPU_prvspace[x]; for (i = 0; i < sizeof(struct mdglobaldata); i += PAGE_SIZE) { va =(vm_offset_t)&CPU_prvspace[x].mdglobaldata + i; m = vm_page_alloc(&kernel_object, va, VM_ALLOC_SYSTEM); pmap_kenter_quick(va, m->phys_addr); - KKASSERT(count < 4); - SMPpt2[count] = pmap_kpte(va); + KKASSERT(i < 4); + SMPpt2[i] = pmap_kpte(va); } for (i = 0; i < sizeof(CPU_prvspace[x].idlestack); i += PAGE_SIZE) { @@ -417,36 +393,6 @@ start_all_aps(u_int boot_addr) pmap_kenter_quick(va, m->phys_addr); } -#if 0 - /* first page of AP's private space */ - pg = x * i386_btop(sizeof(struct privatespace)); - - kprintf("pg: %d, PAGE_SIZE: %d\n", pg, PAGE_SIZE); - /* allocate new private data page(s) */ - gd = (struct mdglobaldata *)kmem_alloc(&kernel_map, - MDGLOBALDATA_BASEALLOC_SIZE); - kprintf("added gd: %p, x: %d, sizeof(gd): %x\n", gd, x, - sizeof(struct mdglobaldata)); - /* wire it into the private page table page */ - for (i = 0; i < MDGLOBALDATA_BASEALLOC_SIZE; i += PAGE_SIZE) { - SMPpt[pg + i / PAGE_SIZE] = (pt_entry_t) - (PG_V | PG_RW | vtophys_pte((char *)gd + i)); - } - pg += MDGLOBALDATA_BASEALLOC_PAGES; - - SMPpt[pg + 0] = 0; /* *gd_CMAP1 */ - SMPpt[pg + 1] = 0; /* *gd_CMAP2 */ - SMPpt[pg + 2] = 0; /* *gd_CMAP3 */ - SMPpt[pg + 3] = 0; /* *gd_PMAP1 */ - - /* allocate and set up an idle stack data page */ - stack = (char *)kmem_alloc(&kernel_map, UPAGES*PAGE_SIZE); - for (i = 0; i < UPAGES; i++) { - SMPpt[pg + 4 + i] = (pt_entry_t) - (PG_V | PG_RW | vtophys_pte(PAGE_SIZE * i + stack)); - } -#endif - gd = &CPU_prvspace[x].mdglobaldata; /* official location */ bzero(gd, sizeof(*gd)); gd->mi.gd_prvspace = ps = &CPU_prvspace[x]; @@ -454,12 +400,7 @@ start_all_aps(u_int boot_addr) /* prime data page for it to use */ mi_gdinit(&gd->mi, x); cpu_gdinit(gd, x); -#if 0 - gd->gd_CMAP1 = &SMPpt[pg + 0]; - gd->gd_CMAP2 = &SMPpt[pg + 1]; - gd->gd_CMAP3 = &SMPpt[pg + 2]; - gd->gd_PMAP1 = &SMPpt[pg + 3]; -#endif + gd->gd_CMAP1 = SMPpt2[0]; gd->gd_CMAP2 = SMPpt2[1]; gd->gd_CMAP3 = SMPpt2[2]; @@ -471,15 +412,6 @@ start_all_aps(u_int boot_addr) gd->mi.gd_ipiq = (void *)kmem_alloc(&kernel_map, sizeof(lwkt_ipiq) * (mp_naps + 1)); bzero(gd->mi.gd_ipiq, sizeof(lwkt_ipiq) * (mp_naps + 1)); -#if 0 - - /* setup a vector to our boot code */ - *((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET; - *((volatile u_short *) WARMBOOT_SEG) = (boot_addr >> 4); - outb(CMOS_REG, BIOS_RESET); - outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */ -#endif - /* * Setup the AP boot stack */ @@ -500,28 +432,10 @@ start_all_aps(u_int boot_addr) arg = (int *)kmem_alloc(&kernel_map, sizeof(int)); *arg = x; -#if 0 - bzero(¶ms, sizeof(params)); - params.func = start_ap; - params.arg = arg; - params.stack = &CPU_prvspace[x].idlestack + sizeof(CPU_prvspace[x].idlestack); - params.stack = bootSTK; - /*params.tid1 = &ap_tids[x];*/ - params.tid1 = NULL; - lwp_create(¶ms); -#endif - kprintf("arg: %p, value = %d\n", arg, *arg); pthread_create(&ap_tids[x], NULL, start_ap, arg); - kprintf("smp_active_mask: %d, smp_startup_mask: %d\n", - smp_active_mask, smp_startup_mask); - kprintf("after pthread_create waiting for cpu%d to start\n", x); - kprintf("1 smp_startup_mask: %d, (1 << x): %d, smp_startup_mask & (1 << x): %d\n", - smp_startup_mask, (1 << x),smp_startup_mask & (1 << x)); while((smp_startup_mask & (1 << x)) == 0) cpu_lfence(); /* XXX spin until the AP has started */ - kprintf("2 smp_startup_mask: %d, (1 << x): %d, smp_startup_mask & (1 << x): %d\n", - smp_startup_mask, (1 << x),smp_startup_mask & (1 << x)); /* XXX hack, sleep for a second to let the APs start up */ sleep(1); -- 2.11.4.GIT