/* ARGSUSED */ static int pool_pset_cpu_setup(cpu_setup_t what, int id, void *arg) { processorid_t cpuid = id; struct setup_arg sarg; int error; cpu_t *c; ASSERT(MUTEX_HELD(&cpu_lock)); ASSERT(INGLOBALZONE(curproc)); if (!pool_pset_enabled()) return (0); if (what != CPU_CONFIG && what != CPU_UNCONFIG && what != CPU_ON && what != CPU_OFF && what != CPU_CPUPART_IN && what != CPU_CPUPART_OUT) return (0); c = cpu_get(cpuid); ASSERT(c != NULL); sarg.psetid = cpupart_query_cpu(c); sarg.cpu = c; sarg.what = what; error = zone_walk(pool_pset_setup_cb, &sarg); ASSERT(error == 0); return (0); }
/* * Find a CPU partition given a processor set ID if the processor set * should be visible from the calling zone. */ cpupart_t * cpupart_find(psetid_t psid) { cpupart_t *cp; ASSERT(MUTEX_HELD(&cpu_lock)); cp = cpupart_find_all(psid); if (cp != NULL && !INGLOBALZONE(curproc) && pool_pset_enabled() && zone_pset_get(curproc->p_zone) != CPTOPS(cp->cp_id)) return (NULL); return (cp); }
static void cpupart_kstat_create(cpupart_t *cp) { kstat_t *ksp; zoneid_t zoneid; ASSERT(MUTEX_HELD(&cpu_lock)); /* * We have a bit of a chicken-egg problem since this code will * get called to create the kstats for CP_DEFAULT before the * pools framework gets initialized. We circumvent the problem * by special-casing cp_default. */ if (cp != &cp_default && pool_pset_enabled()) zoneid = GLOBAL_ZONEID; else zoneid = ALL_ZONES; ksp = kstat_create_zone("unix", cp->cp_id, "pset", "misc", KSTAT_TYPE_NAMED, sizeof (cpupart_kstat_t) / sizeof (kstat_named_t), 0, zoneid); if (ksp != NULL) { cpupart_kstat_t *cpksp = ksp->ks_data; kstat_named_init(&cpksp->cpk_updates, "updates", KSTAT_DATA_UINT64); kstat_named_init(&cpksp->cpk_runnable, "runnable", KSTAT_DATA_UINT64); kstat_named_init(&cpksp->cpk_waiting, "waiting", KSTAT_DATA_UINT64); kstat_named_init(&cpksp->cpk_ncpus, "ncpus", KSTAT_DATA_UINT32); kstat_named_init(&cpksp->cpk_avenrun_1min, "avenrun_1min", KSTAT_DATA_UINT32); kstat_named_init(&cpksp->cpk_avenrun_5min, "avenrun_5min", KSTAT_DATA_UINT32); kstat_named_init(&cpksp->cpk_avenrun_15min, "avenrun_15min", KSTAT_DATA_UINT32); ksp->ks_update = cpupart_kstat_update; ksp->ks_private = cp; kstat_install(ksp); } cp->cp_kstat = ksp; }
/* * Create interrupt kstats for this CPU. */ void cpu_create_intrstat(cpu_t *cp) { int i; kstat_t *intr_ksp; kstat_named_t *knp; char name[KSTAT_STRLEN]; zoneid_t zoneid; ASSERT(MUTEX_HELD(&cpu_lock)); if (pool_pset_enabled()) zoneid = GLOBAL_ZONEID; else zoneid = ALL_ZONES; intr_ksp = kstat_create_zone("cpu", cp->cpu_id, "intrstat", "misc", KSTAT_TYPE_NAMED, PIL_MAX * 2, NULL, zoneid); /* * Initialize each PIL's named kstat */ if (intr_ksp != NULL) { intr_ksp->ks_update = cpu_kstat_intrstat_update; knp = (kstat_named_t *)intr_ksp->ks_data; intr_ksp->ks_private = cp; for (i = 0; i < PIL_MAX; i++) { (void) snprintf(name, KSTAT_STRLEN, "level-%d-time", i + 1); kstat_named_init(&knp[i * 2], name, KSTAT_DATA_UINT64); (void) snprintf(name, KSTAT_STRLEN, "level-%d-count", i + 1); kstat_named_init(&knp[(i * 2) + 1], name, KSTAT_DATA_UINT64); } kstat_install(intr_ksp); } }
/* * Return list of active processor sets, up to a maximum indicated by * numpsets. The total number of processor sets is stored in the * location pointed to by numpsets. */ static int pset_list(psetid_t *psetlist, uint_t *numpsets) { uint_t user_npsets = 0; uint_t real_npsets; psetid_t *psets = NULL; int error = 0; if (numpsets != NULL) { if (copyin(numpsets, &user_npsets, sizeof (uint_t)) != 0) return (set_errno(EFAULT)); } /* * Get the list of all processor sets. First we need to find * out how many there are, so we can allocate a large enough * buffer. */ mutex_enter(&cpu_lock); if (!INGLOBALZONE(curproc) && pool_pset_enabled()) { psetid_t psetid = zone_pset_get(curproc->p_zone); if (psetid == PS_NONE) { real_npsets = 0; } else { real_npsets = 1; psets = kmem_alloc(real_npsets * sizeof (psetid_t), KM_SLEEP); psets[0] = psetid; } } else { real_npsets = cpupart_list(0, NULL, CP_ALL); if (real_npsets) { psets = kmem_alloc(real_npsets * sizeof (psetid_t), KM_SLEEP); (void) cpupart_list(psets, real_npsets, CP_ALL); } } mutex_exit(&cpu_lock); if (user_npsets > real_npsets) user_npsets = real_npsets; if (numpsets != NULL) { if (copyout(&real_npsets, numpsets, sizeof (uint_t)) != 0) error = EFAULT; else if (psetlist != NULL && user_npsets != 0) { if (copyout(psets, psetlist, user_npsets * sizeof (psetid_t)) != 0) error = EFAULT; } } if (real_npsets) kmem_free(psets, real_npsets * sizeof (psetid_t)); if (error) return (set_errno(error)); else return (0); }