static void disable_hyperthread(void) { unsigned long share[MAX_BITMASK_LEN]; int cpu; int bitmask_idx = 0; int i=0, count=0; bitmask_idx = CPUELT(common -> num_procs); for(i=0; i< bitmask_idx; i++){ common -> avail[count++] = 0xFFFFFFFFFFFFFFFFUL; } if(CPUMASK(common -> num_procs) != 1){ common -> avail[count++] = CPUMASK(common -> num_procs) - 1; } common -> avail_count = count; /* if(common->num_procs > 64){ */ /* fprintf(stderr, "\nOpenBLAS Warning : The number of CPU/Cores(%d) is beyond the limit(64). Terminated.\n", common->num_procs); */ /* exit(1); */ /* }else if(common->num_procs == 64){ */ /* common -> avail = 0xFFFFFFFFFFFFFFFFUL; */ /* }else */ /* common -> avail = (1UL << common -> num_procs) - 1; */ #ifdef DEBUG fprintf(stderr, "\nAvail CPUs : "); for(i=0; i<count; i++) fprintf(stderr, "%04lx ", common -> avail[i]); fprintf(stderr, ".\n"); #endif for (cpu = 0; cpu < common -> num_procs; cpu ++) { get_share(cpu, 1, share); //When the shared cpu are in different element of share & avail array, this may be a bug. for (i = 0; i < count ; i++){ share[i] &= common->avail[i]; if (popcount(share[i]) > 1) { #ifdef DEBUG fprintf(stderr, "Detected Hyper Threading on CPU %4x; disabled CPU %04lx.\n", cpu, share[i] & ~(CPUMASK(cpu))); #endif common -> avail[i] &= ~((share[i] & ~ CPUMASK(cpu))); } } } }
/* * Find the nth present CPU and return its pc_cpuid as well as set the * pc_acpi_id from the most reliable source. */ static int acpi_cpu_get_id(uint32_t idx, uint32_t *acpi_id, uint32_t *cpu_id) { struct mdglobaldata *md; uint32_t i; KASSERT(acpi_id != NULL, ("Null acpi_id")); KASSERT(cpu_id != NULL, ("Null cpu_id")); for (i = 0; i < ncpus; i++) { if ((smp_active_mask & CPUMASK(i)) == 0) continue; md = (struct mdglobaldata *)globaldata_find(i); KASSERT(md != NULL, ("no pcpu data for %d", i)); if (idx-- == 0) { /* * If pc_acpi_id was not initialized (e.g., a non-APIC UP box) * override it with the value from the ASL. Otherwise, if the * two don't match, prefer the MADT-derived value. Finally, * return the pc_cpuid to reference this processor. */ if (md->gd_acpi_id == 0xffffffff) md->gd_acpi_id = *acpi_id; else if (md->gd_acpi_id != *acpi_id) *acpi_id = md->gd_acpi_id; *cpu_id = md->mi.gd_cpuid; return 0; } } return ESRCH; }
/* * Get SMP fully working before we start initializing devices. */ static void ap_finish(void) { int i; cpumask_t ncpus_mask = 0; for (i = 1; i <= ncpus; i++) ncpus_mask |= CPUMASK(i); mp_finish = 1; if (bootverbose) kprintf("Finish MP startup\n"); /* build our map of 'other' CPUs */ mycpu->gd_other_cpus = smp_startup_mask & ~CPUMASK(mycpu->gd_cpuid); /* * Let the other cpu's finish initializing and build their map * of 'other' CPUs. */ rel_mplock(); while (smp_active_mask != smp_startup_mask) { DELAY(100000); cpu_lfence(); } while (try_mplock() == 0) DELAY(100000); if (bootverbose) kprintf("Active CPU Mask: %08x\n", smp_active_mask); }
static inline void get_share(int cpu, int level, unsigned long * share) { int infile; unsigned long affinity[32]; char cpumap[160]; char name[160]; char *dummy; int count=0; int i=0,k=0; int bitmask_idx = 0; sprintf(name, SHARE_NAME, cpu, level); infile = open(name, O_RDONLY); // Init share for(i=0; i<MAX_BITMASK_LEN; i++){ share[i]=0; } bitmask_idx = CPUELT(cpu); share[bitmask_idx] = CPUMASK(cpu); if (infile != -1) { read(infile, cpumap, sizeof(cpumap)); for(i=0; i<160; i++){ if(cpumap[i] == '\n') break; if(cpumap[i] != ','){ name[k++]=cpumap[i]; //Enough data if(k >= NCPUBITS/4){ affinity[count++] = strtoul(name, &dummy, 16); k=0; } } } if(k!=0){ name[k]='\0'; affinity[count++] = strtoul(name, &dummy, 16); k=0; } // 0-63bit -> node_info[0], 64-128bit -> node_info[1] .... // revert the sequence for(i=0; i<count && i<MAX_BITMASK_LEN; i++){ share[i]=affinity[count-i-1]; } close(infile); } return ; }
static void disable_affinity(void) { int i=0; int bitmask_idx=0; int count=0; #ifdef DEBUG fprintf(stderr, "Final all available CPUs : %04lx.\n\n", common -> avail[0]); fprintf(stderr, "CPU mask : %04lx.\n\n", *(unsigned long *)&cpu_orig_mask[0]); #endif /* if(common->final_num_procs > 64){ */ /* fprintf(stderr, "\nOpenBLAS Warining : The number of CPU/Cores(%d) is beyond the limit(64). Terminated.\n", common->final_num_procs); */ /* exit(1); */ /* }else if(common->final_num_procs == 64){ */ /* lprocmask = 0xFFFFFFFFFFFFFFFFUL; */ /* }else */ /* lprocmask = (1UL << common -> final_num_procs) - 1; */ bitmask_idx = CPUELT(common -> final_num_procs); for(i=0; i< bitmask_idx; i++){ lprocmask[count++] = 0xFFFFFFFFFFFFFFFFUL; } if(CPUMASK(common -> final_num_procs) != 1){ lprocmask[count++] = CPUMASK(common -> final_num_procs) - 1; } lprocmask_count = count; #ifndef USE_OPENMP for(i=0; i< count; i++){ lprocmask[i] &= common->avail[i]; } #endif #ifdef DEBUG fprintf(stderr, "I choose these CPUs : %04lx.\n\n", lprocmask[0]); #endif }
static void cpu_reset_proxy(void) { cpu_reset_proxy_active = 1; while (cpu_reset_proxy_active == 1) ; /* Wait for other cpu to disable interupts */ kprintf("cpu_reset_proxy: Grabbed mp lock for BSP\n"); cpu_reset_proxy_active = 3; while (cpu_reset_proxy_active == 3) ; /* Wait for other cpu to enable interrupts */ stop_cpus(CPUMASK(cpu_reset_proxyid)); kprintf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid); DELAY(1000000); cpu_reset_real(); }
/* * Initialize per-cpu polling(4) context. Called from kern_clock.c: */ void init_device_poll_pcpu(int cpuid) { struct pollctx *pctx; char cpuid_str[3]; if (cpuid >= POLLCTX_MAX) return; if ((CPUMASK(cpuid) & poll_cpumask0) == 0) return; if (poll_burst_max < MIN_POLL_BURST_MAX) poll_burst_max = MIN_POLL_BURST_MAX; else if (poll_burst_max > MAX_POLL_BURST_MAX) poll_burst_max = MAX_POLL_BURST_MAX; if (poll_each_burst > poll_burst_max) poll_each_burst = poll_burst_max; poll_cpumask |= CPUMASK(cpuid); pctx = kmalloc(sizeof(*pctx), M_DEVBUF, M_WAITOK | M_ZERO); pctx->poll_each_burst = poll_each_burst; pctx->poll_burst_max = poll_burst_max; pctx->user_frac = 50; pctx->reg_frac = 20; pctx->polling_enabled = polling_enabled; pctx->pollhz = pollhz; pctx->poll_cpuid = cpuid; poll_reset_state(pctx); netmsg_init(&pctx->poll_netmsg, NULL, &netisr_adone_rport, 0, netisr_poll); #ifdef INVARIANTS pctx->poll_netmsg.lmsg.u.ms_resultp = pctx; #endif netmsg_init(&pctx->poll_more_netmsg, NULL, &netisr_adone_rport, 0, netisr_pollmore); #ifdef INVARIANTS pctx->poll_more_netmsg.lmsg.u.ms_resultp = pctx; #endif KASSERT(cpuid < POLLCTX_MAX, ("cpu id must < %d", cpuid)); poll_context[cpuid] = pctx; if (poll_defcpu < 0) { poll_defcpu = cpuid; /* * Initialize global sysctl nodes, for compat */ poll_add_sysctl(NULL, SYSCTL_STATIC_CHILDREN(_kern_polling), pctx); } /* * Initialize per-cpu sysctl nodes */ ksnprintf(cpuid_str, sizeof(cpuid_str), "%d", pctx->poll_cpuid); sysctl_ctx_init(&pctx->poll_sysctl_ctx); pctx->poll_sysctl_tree = SYSCTL_ADD_NODE(&pctx->poll_sysctl_ctx, SYSCTL_STATIC_CHILDREN(_kern_polling), OID_AUTO, cpuid_str, CTLFLAG_RD, 0, ""); poll_add_sysctl(&pctx->poll_sysctl_ctx, SYSCTL_CHILDREN(pctx->poll_sysctl_tree), pctx); /* * Initialize systimer */ systimer_init_periodic_nq(&pctx->pollclock, pollclock, pctx, 1); }
static void numa_mapping(void) { int node, cpu, core; int i, j, h; unsigned long work, bit; int count = 0; int bitmask_idx = 0; for (node = 0; node < common -> num_nodes; node ++) { core = 0; for (cpu = 0; cpu < common -> num_procs; cpu ++) { bitmask_idx = CPUELT(cpu); if (common -> node_info[node][bitmask_idx] & common -> avail[bitmask_idx] & CPUMASK(cpu)) { common -> cpu_info[count] = WRITE_CORE(core) | WRITE_NODE(node) | WRITE_CPU(cpu); count ++; core ++; } } } #ifdef DEBUG fprintf(stderr, "\nFrom /sys ...\n\n"); for (cpu = 0; cpu < count; cpu++) fprintf(stderr, "CPU (%2d) : %08lx\n", cpu, common -> cpu_info[cpu]); #endif h = 1; while (h < count) h = 2 * h + 1; while (h > 1) { h /= 2; for (i = h; i < count; i++) { work = common -> cpu_info[i]; bit = CPU_ISSET(i, &cpu_orig_mask[0]); j = i - h; while (work < common -> cpu_info[j]) { common -> cpu_info[j + h] = common -> cpu_info[j]; if (CPU_ISSET(j, &cpu_orig_mask[0])) { CPU_SET(j + h, &cpu_orig_mask[0]); } else { CPU_CLR(j + h, &cpu_orig_mask[0]); } j -= h; if (j < 0) break; } common -> cpu_info[j + h] = work; if (bit) { CPU_SET(j + h, &cpu_orig_mask[0]); } else { CPU_CLR(j + h, &cpu_orig_mask[0]); } } } #ifdef DEBUG fprintf(stderr, "\nSorting ...\n\n"); for (cpu = 0; cpu < count; cpu++) fprintf(stderr, "CPU (%2d) : %08lx\n", cpu, common -> cpu_info[cpu]); #endif }