Пример #1
0
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)));
      }
    }
  }
}
Пример #2
0
/*
 * 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;
}
Пример #3
0
/*
 * 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);
}
Пример #4
0
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 ;
}
Пример #5
0
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

}
Пример #6
0
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();
}
Пример #7
0
/*
 * 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);
}
Пример #8
0
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

}