kernel - Add kern.usched_global_cpumask
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 2 Feb 2011 07:44:07 +0000 (23:44 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 2 Feb 2011 07:44:07 +0000 (23:44 -0800)
* Add sysctl kern.usched_global_cpumask, a global cpumask that restricts
  which cpus userland processes are allowed to run on.  This sysctl may be
  set dynamically.

* NOTE: This sysctl is intended to be used by powerd.  Setting it manually
  will only work properly if powerd is not running.

sys/kern/init_main.c
sys/kern/usched_bsd4.c
sys/sys/systm.h

index 6d59388..deceac6 100644 (file)
@@ -97,12 +97,15 @@ struct thread thread0;
 
 int cmask = CMASK;
 u_int cpu_mi_feature;
+cpumask_t usched_global_cpumask;
 extern struct user *proc0paddr;
 extern int fallback_elf_brand;
 
 int    boothowto = 0;          /* initialized so that it can be patched */
 SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD, &boothowto, 0,
     "Reboot flags, from console subsystem");
+SYSCTL_ULONG(_kern, OID_AUTO, usched_global_cpumask, CTLFLAG_RW,
+    &usched_global_cpumask, 0, "global user scheduler cpumask");
 
 /*
  * This ensures that there is at least one entry so that the sysinit_set
@@ -706,5 +709,6 @@ mi_gdinit(struct globaldata *gd, int cpuid)
        lwkt_gdinit(gd);
        vm_map_entry_reserve_cpu_init(gd);
        sleep_gdinit(gd);
+       usched_global_cpumask |= CPUMASK(cpuid);
 }
 
index 1f9fe99..d3f9b21 100644 (file)
@@ -503,7 +503,7 @@ bsd4_setrunqueue(struct lwp *lp)
        ++bsd4_scancpu;
        cpuid = (bsd4_scancpu & 0xFFFF) % ncpus;
        mask = ~bsd4_curprocmask & bsd4_rdyprocmask & lp->lwp_cpumask &
-              smp_active_mask;
+              smp_active_mask & usched_global_cpumask;
 
        while (mask) {
                tmpmask = ~(CPUMASK(cpuid) - 1);
@@ -523,7 +523,7 @@ bsd4_setrunqueue(struct lwp *lp)
         * Then cpus which might have a currently running lp
         */
        mask = bsd4_curprocmask & bsd4_rdyprocmask &
-              lp->lwp_cpumask & smp_active_mask;
+              lp->lwp_cpumask & smp_active_mask & usched_global_cpumask;
 
        while (mask) {
                tmpmask = ~(CPUMASK(cpuid) - 1);
@@ -544,10 +544,16 @@ bsd4_setrunqueue(struct lwp *lp)
         * and round-robin.  Other cpus will pickup as they release their
         * current lwps or become ready.
         *
+        * Avoid a degenerate system lockup case if usched_global_cpumask
+        * is set to 0 or otherwise does not cover lwp_cpumask.
+        *
         * We only kick the target helper thread in this case, we do not
         * set the user resched flag because
         */
        cpuid = (bsd4_scancpu & 0xFFFF) % ncpus;
+       if ((CPUMASK(cpuid) & usched_global_cpumask) == 0) {
+               cpuid = 0;
+       }
        gd = globaldata_find(cpuid);
        dd = &bsd4_pcpu[cpuid];
 found:
index 8bd8408..0c0de4e 100644 (file)
@@ -99,6 +99,7 @@ extern int clocks_running;    /* timing/timeout subsystem is operational */
 extern u_int cpu_feature;      /* CPUID_* features */
 extern u_int cpu_feature2;     /* CPUID2_* features */
 extern u_int cpu_mi_feature;   /* CPU_MI_XXX machine-nonspecific features */
+extern cpumask_t usched_global_cpumask;
 
 extern int nfs_diskless_valid; /* NFS diskless params were obtained */
 extern vm_paddr_t Maxmem;      /* Highest physical memory address in system */