Index: sys/kern/sched_ule.c =================================================================== --- sys/kern/sched_ule.c +++ sys/kern/sched_ule.c @@ -251,6 +251,7 @@ struct runq tdq_realtime; /* real-time run queue. */ struct runq tdq_timeshare; /* timeshare run queue. */ struct runq tdq_idle; /* Queue of IDLE threads. */ + sbintime_t tdq_next_steal; /* When can we attempt to steal. */ char tdq_name[TDQ_NAME_LEN]; #ifdef KTR char tdq_loadname[TDQ_LOADNAME_LEN]; @@ -277,6 +278,7 @@ static int __read_mostly steal_thresh = 2; static int __read_mostly always_steal = 0; static int __read_mostly trysteal_limit = 2; +static int __read_mostly steal_interval; /* * One thread queue per processor. @@ -976,6 +978,22 @@ return (td); } +#ifdef SMP +static bool +tdq_can_steal(struct tdq *tdq) +{ + sbintime_t now; + + if (steal_interval != 0) { + now = getsbinuptime(); + if (now < tdq->tdq_next_steal) + return (false); + tdq->tdq_next_steal = now + steal_interval * SBT_1US; + } + return (true); +} +#endif + /* * This tdq has idled. Try to steal a thread from another cpu and switch * to it. @@ -990,6 +1008,10 @@ if (smp_started == 0 || steal_idle == 0 || tdq->tdq_cg == NULL) return (1); +#ifdef SMP + if (!tdq_can_steal(tdq)) + return (1); +#endif CPU_FILL(&mask); CPU_CLR(PCPU_GET(cpuid), &mask); restart: @@ -1923,7 +1945,8 @@ cpuset_t mask; int cpu, i; - if (smp_started == 0 || trysteal_limit == 0 || tdq->tdq_cg == NULL) + if (smp_started == 0 || trysteal_limit == 0 || tdq->tdq_cg == NULL || + !tdq_can_steal(tdq)) return; CPU_FILL(&mask); CPU_CLR(PCPU_GET(cpuid), &mask); @@ -3121,6 +3144,9 @@ 0, "Topological distance limit for stealing threads in sched_switch()"); SYSCTL_INT(_kern_sched, OID_AUTO, always_steal, CTLFLAG_RW, &always_steal, 0, "Always run the stealer from the idle thread"); +SYSCTL_INT(_kern_sched, OID_AUTO, steal_interval, CTLFLAG_RWTUN, + &steal_interval, 0, + "Steal work only every steal_interval microseconds"); SYSCTL_PROC(_kern_sched, OID_AUTO, topology_spec, CTLTYPE_STRING | CTLFLAG_MPSAFE | CTLFLAG_RD, NULL, 0, sysctl_kern_sched_topology_spec, "A", "XML dump of detected CPU topology");