summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2003-11-02 10:56:48 +0000
committerjeff <jeff@FreeBSD.org>2003-11-02 10:56:48 +0000
commit40aa6873efd7f7296719f01271f7b315d59b0b7c (patch)
tree8b9dc8ec34a95a905bffd9a6326d3a9ba292303e /sys/kern
parenta3bf188d5b14acb242cc0a64b6bbfe2797f04d04 (diff)
downloadFreeBSD-src-40aa6873efd7f7296719f01271f7b315d59b0b7c.zip
FreeBSD-src-40aa6873efd7f7296719f01271f7b315d59b0b7c.tar.gz
- Remove the ksq_loads[] array. We are only interested in three counts,
the total load, the timeshare load, and the number of threads that can be migrated to another cpu. Account for these seperately. - Introduce a KSE_CAN_MIGRATE() macro which determines whether or not a KSE can be migrated to another CPU. Currently, this only checks to see if we're an interrupt handler. Eventually this will also be used to support CPU binding.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/sched_ule.c83
1 files changed, 50 insertions, 33 deletions
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 1069342..39f2bdd 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -209,11 +209,12 @@ struct kseq {
struct runq ksq_timeshare[2]; /* Run queues for !IDLE. */
struct runq *ksq_next; /* Next timeshare queue. */
struct runq *ksq_curr; /* Current queue. */
- int ksq_loads[KSEQ_NCLASS]; /* Load for each class */
+ int ksq_load_timeshare; /* Load for timeshare. */
int ksq_load; /* Aggregate load. */
short ksq_nice[SCHED_PRI_NRESV]; /* KSEs in each nice bin. */
short ksq_nicemin; /* Least nice. */
#ifdef SMP
+ int ksq_load_transferable; /* kses that may be migrated. */
unsigned int ksq_rslices; /* Slices on run queue */
int ksq_cpus; /* Count of CPUs in this kseq. */
struct kse *ksq_assigned; /* KSEs assigned by another CPU. */
@@ -262,6 +263,7 @@ static int kseq_find(void);
static void kseq_notify(struct kse *ke, int cpu);
static void kseq_assign(struct kseq *);
static struct kse *kseq_steal(struct kseq *kseq);
+#define KSE_CAN_MIGRATE(ke, class) ((class) != PRI_ITHD)
#endif
void
@@ -274,10 +276,10 @@ kseq_print(int cpu)
printf("kseq:\n");
printf("\tload: %d\n", kseq->ksq_load);
- printf("\tload ITHD: %d\n", kseq->ksq_loads[PRI_ITHD]);
- printf("\tload REALTIME: %d\n", kseq->ksq_loads[PRI_REALTIME]);
- printf("\tload TIMESHARE: %d\n", kseq->ksq_loads[PRI_TIMESHARE]);
- printf("\tload IDLE: %d\n", kseq->ksq_loads[PRI_IDLE]);
+ printf("\tload REALTIME: %d\n", kseq->ksq_load_timeshare);
+#ifdef SMP
+ printf("\tload transferable: %d\n", kseq->ksq_load_transferable);
+#endif
printf("\tnicemin:\t%d\n", kseq->ksq_nicemin);
printf("\tnice counts:\n");
for (i = 0; i < SCHED_PRI_NRESV; i++)
@@ -289,8 +291,16 @@ kseq_print(int cpu)
static void
kseq_add(struct kseq *kseq, struct kse *ke)
{
+ int class;
mtx_assert(&sched_lock, MA_OWNED);
- kseq->ksq_loads[PRI_BASE(ke->ke_ksegrp->kg_pri_class)]++;
+ class = PRI_BASE(ke->ke_ksegrp->kg_pri_class);
+ if (class == PRI_TIMESHARE)
+ kseq->ksq_load_timeshare++;
+#ifdef SMP
+ if (KSE_CAN_MIGRATE(ke, class))
+ kseq->ksq_load_transferable++;
+ kseq->ksq_rslices += ke->ke_slice;
+#endif
kseq->ksq_load++;
if (ke->ke_ksegrp->kg_pri_class == PRI_TIMESHARE)
CTR6(KTR_ULE, "Add kse %p to %p (slice: %d, pri: %d, nice: %d(%d))",
@@ -298,23 +308,25 @@ kseq_add(struct kseq *kseq, struct kse *ke)
ke->ke_ksegrp->kg_nice, kseq->ksq_nicemin);
if (ke->ke_ksegrp->kg_pri_class == PRI_TIMESHARE)
kseq_nice_add(kseq, ke->ke_ksegrp->kg_nice);
-#ifdef SMP
- kseq->ksq_rslices += ke->ke_slice;
-#endif
}
static void
kseq_rem(struct kseq *kseq, struct kse *ke)
{
+ int class;
mtx_assert(&sched_lock, MA_OWNED);
- kseq->ksq_loads[PRI_BASE(ke->ke_ksegrp->kg_pri_class)]--;
+ class = PRI_BASE(ke->ke_ksegrp->kg_pri_class);
+ if (class == PRI_TIMESHARE)
+ kseq->ksq_load_timeshare--;
+#ifdef SMP
+ if (KSE_CAN_MIGRATE(ke, class))
+ kseq->ksq_load_transferable--;
+ kseq->ksq_rslices -= ke->ke_slice;
+#endif
kseq->ksq_load--;
ke->ke_runq = NULL;
if (ke->ke_ksegrp->kg_pri_class == PRI_TIMESHARE)
kseq_nice_rem(kseq, ke->ke_ksegrp->kg_nice);
-#ifdef SMP
- kseq->ksq_rslices -= ke->ke_slice;
-#endif
}
static void
@@ -323,7 +335,7 @@ kseq_nice_add(struct kseq *kseq, int nice)
mtx_assert(&sched_lock, MA_OWNED);
/* Normalize to zero. */
kseq->ksq_nice[nice + SCHED_PRI_NHALF]++;
- if (nice < kseq->ksq_nicemin || kseq->ksq_loads[PRI_TIMESHARE] == 1)
+ if (nice < kseq->ksq_nicemin || kseq->ksq_load_timeshare == 1)
kseq->ksq_nicemin = nice;
}
@@ -345,7 +357,7 @@ kseq_nice_rem(struct kseq *kseq, int nice)
*/
if (nice != kseq->ksq_nicemin ||
kseq->ksq_nice[n] != 0 ||
- kseq->ksq_loads[PRI_TIMESHARE] == 0)
+ kseq->ksq_load_timeshare == 0)
return;
for (; n < SCHED_PRI_NRESV; n++)
@@ -409,8 +421,7 @@ kseq_balance(void *arg)
kseq = KSEQ_CPU(high_cpu);
- high_load = kseq->ksq_loads[PRI_IDLE] + kseq->ksq_loads[PRI_TIMESHARE] +
- kseq->ksq_loads[PRI_REALTIME];
+ high_load = kseq->ksq_load_transferable;
/*
* Nothing to do.
*/
@@ -460,8 +471,7 @@ kseq_load_highest(void)
}
kseq = KSEQ_CPU(cpu);
- if ((kseq->ksq_loads[PRI_IDLE] + kseq->ksq_loads[PRI_TIMESHARE] +
- kseq->ksq_loads[PRI_REALTIME]) > kseq->ksq_cpus)
+ if (kseq->ksq_load_transferable > kseq->ksq_cpus)
return (kseq);
return (NULL);
@@ -572,8 +582,8 @@ runq_steal(struct runq *rq)
continue;
rqh = &rq->rq_queues[bit + (word << RQB_L2BPW)];
TAILQ_FOREACH(ke, rqh, ke_procq) {
- if (PRI_BASE(ke->ke_ksegrp->kg_pri_class) !=
- PRI_ITHD)
+ if (KSE_CAN_MIGRATE(ke,
+ PRI_BASE(ke->ke_ksegrp->kg_pri_class)))
return (ke);
}
}
@@ -644,16 +654,12 @@ kseq_setup(struct kseq *kseq)
runq_init(&kseq->ksq_timeshare[0]);
runq_init(&kseq->ksq_timeshare[1]);
runq_init(&kseq->ksq_idle);
-
kseq->ksq_curr = &kseq->ksq_timeshare[0];
kseq->ksq_next = &kseq->ksq_timeshare[1];
-
- kseq->ksq_loads[PRI_ITHD] = 0;
- kseq->ksq_loads[PRI_REALTIME] = 0;
- kseq->ksq_loads[PRI_TIMESHARE] = 0;
- kseq->ksq_loads[PRI_IDLE] = 0;
kseq->ksq_load = 0;
+ kseq->ksq_load_timeshare = 0;
#ifdef SMP
+ kseq->ksq_load_transferable = 0;
kseq->ksq_rslices = 0;
kseq->ksq_assigned = NULL;
#endif
@@ -773,7 +779,7 @@ sched_slice(struct kse *ke)
int nice;
nice = kg->kg_nice + (0 - kseq->ksq_nicemin);
- if (kseq->ksq_loads[PRI_TIMESHARE] == 0 ||
+ if (kseq->ksq_load_timeshare == 0 ||
kg->kg_nice < kseq->ksq_nicemin)
ke->ke_slice = SCHED_SLICE_MAX;
else if (nice <= SCHED_SLICE_NTHRESH)
@@ -788,7 +794,7 @@ sched_slice(struct kse *ke)
CTR6(KTR_ULE,
"Sliced %p(%d) (nice: %d, nicemin: %d, load: %d, interactive: %d)",
ke, ke->ke_slice, kg->kg_nice, kseq->ksq_nicemin,
- kseq->ksq_loads[PRI_TIMESHARE], SCHED_INTERACTIVE(kg));
+ kseq->ksq_load_timeshare, SCHED_INTERACTIVE(kg));
return;
}
@@ -1125,19 +1131,31 @@ sched_class(struct ksegrp *kg, int class)
{
struct kseq *kseq;
struct kse *ke;
+ int nclass;
+ int oclass;
mtx_assert(&sched_lock, MA_OWNED);
if (kg->kg_pri_class == class)
return;
+ nclass = PRI_BASE(class);
+ oclass = PRI_BASE(kg->kg_pri_class);
FOREACH_KSE_IN_GROUP(kg, ke) {
if (ke->ke_state != KES_ONRUNQ &&
ke->ke_state != KES_THREAD)
continue;
kseq = KSEQ_CPU(ke->ke_cpu);
- kseq->ksq_loads[PRI_BASE(kg->kg_pri_class)]--;
- kseq->ksq_loads[PRI_BASE(class)]++;
+#ifdef SMP
+ if (KSE_CAN_MIGRATE(ke, oclass))
+ kseq->ksq_load_transferable--;
+ if (KSE_CAN_MIGRATE(ke, nclass))
+ kseq->ksq_load_transferable++;
+#endif
+ if (oclass == PRI_TIMESHARE)
+ kseq->ksq_load_timeshare--;
+ if (nclass == PRI_TIMESHARE)
+ kseq->ksq_load_timeshare++;
if (kg->kg_pri_class == PRI_TIMESHARE)
kseq_nice_rem(kseq, kg->kg_nice);
@@ -1405,8 +1423,7 @@ sched_add(struct thread *td)
* If there are any idle processors, give them our extra load.
*/
if (kseq_idle && class != PRI_ITHD &&
- (kseq->ksq_loads[PRI_IDLE] + kseq->ksq_loads[PRI_TIMESHARE] +
- kseq->ksq_loads[PRI_REALTIME]) >= kseq->ksq_cpus) {
+ kseq->ksq_load_transferable >= kseq->ksq_cpus) {
int cpu;
/*
OpenPOWER on IntegriCloud