Page MenuHomeFreeBSD

D35644.id108040.diff
No OneTemporary

D35644.id108040.diff

Index: sys/kern/sched_ule.c
===================================================================
--- sys/kern/sched_ule.c
+++ sys/kern/sched_ule.c
@@ -45,6 +45,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/counter.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
@@ -298,6 +299,9 @@
#define TDQ_CPU(x) (&tdq_cpu)
#endif
+static COUNTER_U64_DEFINE_EARLY(ithread_demotions);
+static COUNTER_U64_DEFINE_EARLY(ithread_preemptions);
+
#define TDQ_LOCK_ASSERT(t, type) mtx_assert(TDQ_LOCKPTR((t)), (type))
#define TDQ_LOCK(t) mtx_lock_spin(TDQ_LOCKPTR((t)))
#define TDQ_LOCK_FLAGS(t, f) mtx_lock_spin_flags(TDQ_LOCKPTR((t)), (f))
@@ -2336,6 +2340,15 @@
sched_interact_update(td);
sched_pctcpu_update(ts, 0);
}
+
+ /*
+ * When resuming an idle ithread, restore its base ithread
+ * priority.
+ */
+ if (PRI_BASE(td->td_pri_class) == PRI_ITHD &&
+ td->td_priority != td->td_base_ithread_pri)
+ sched_prio(td, td->td_base_ithread_pri);
+
/*
* Reset the slice value since we slept and advanced the round-robin.
*/
@@ -2503,9 +2516,21 @@
thread_unlock(td);
}
+/*
+ * Return time slice for a given thread. For ithreads this is
+ * sched_slice. For other threads it is tdq_slice(tdq).
+ */
+static inline int
+td_slice(struct thread *td, struct tdq *tdq)
+{
+ if (PRI_BASE(td->td_pri_class) == PRI_ITHD)
+ return (sched_slice);
+ return (tdq_slice(tdq));
+}
+
/*
* Handle a stathz tick. This is really only relevant for timeshare
- * threads.
+ * and interrupt threads.
*/
void
sched_clock(struct thread *td, int cnt)
@@ -2562,9 +2587,22 @@
* time slice (default is 100ms).
*/
ts->ts_slice += cnt;
- if (ts->ts_slice >= tdq_slice(tdq)) {
+ if (ts->ts_slice >= td_slice(td, tdq)) {
ts->ts_slice = 0;
- td->td_flags |= TDF_NEEDRESCHED | TDF_SLICEEND;
+
+ /*
+ * If an ithread uses a full quantum, demote its
+ * priority and preempt it.
+ */
+ if (PRI_BASE(td->td_pri_class) == PRI_ITHD) {
+ counter_u64_add(ithread_preemptions, 1);
+ td->td_owepreempt = 1;
+ if (td->td_base_pri + RQ_PPQ < PRI_MAX_ITHD) {
+ counter_u64_add(ithread_demotions, 1);
+ sched_prio(td, td->td_base_pri + RQ_PPQ);
+ }
+ } else
+ td->td_flags |= TDF_NEEDRESCHED | TDF_SLICEEND;
}
}
@@ -3270,3 +3308,12 @@
static int ccpu = 0;
SYSCTL_INT(_kern, OID_AUTO, ccpu, CTLFLAG_RD, &ccpu, 0,
"Decay factor used for updating %CPU in 4BSD scheduler");
+
+SYSCTL_NODE(_kern_sched, OID_AUTO, ithread, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+ "Interrupt thread stats");
+SYSCTL_COUNTER_U64(_kern_sched_ithread, OID_AUTO, demotions,
+ CTLFLAG_RD, &ithread_demotions,
+ "Count of interrupt thread priority demotions");
+SYSCTL_COUNTER_U64(_kern_sched_ithread, OID_AUTO, preemptions,
+ CTLFLAG_RD, &ithread_preemptions,
+ "Count of interrupt thread preemptions due to time-sharing");

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 7, 11:22 PM (4 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38444013
Default Alt Text
D35644.id108040.diff (2 KB)

Event Timeline