PERFORCE change 86091 for review
Robert Watson
rwatson at FreeBSD.org
Sun Oct 30 15:46:43 PST 2005
http://perforce.freebsd.org/chv.cgi?CH=86091
Change 86091 by rwatson at rwatson_peppercorn on 2005/10/30 23:45:49
Not entirely pretty hack: allow preemption by the netisr thread to
be configurable separate from global preemption. Specifically, if
net.isr.preempt=0, pass SWI_NOPREEMPT to swi_sched(). Implement
SWI_NOPREEMPT by adding IE_FLAG_NOPREEMPT (don't preempt due to an
interrupt event, only wakeup), which in turn is implemented by
adding SRQ_NOPREEMPT, a flag to the scheduler run queue calls.
The reason to add this is that loopback traffic is seeing a lot of
context switches, and avoiding the context switches through
avoiding unnecessary preemption may help illustrate if this is a
performance problem, and possibly be part of a fix.
This may not work, either functionally, or in its overall goal, and
is an experiment.
Affected files ...
.. //depot/projects/netsmp/src/sys/kern/kern_intr.c#4 edit
.. //depot/projects/netsmp/src/sys/kern/sched_4bsd.c#2 edit
.. //depot/projects/netsmp/src/sys/kern/sched_ule.c#6 edit
.. //depot/projects/netsmp/src/sys/net/netisr.c#3 edit
.. //depot/projects/netsmp/src/sys/sys/interrupt.h#4 edit
.. //depot/projects/netsmp/src/sys/sys/proc.h#5 edit
Differences ...
==== //depot/projects/netsmp/src/sys/kern/kern_intr.c#4 (text+ko) ====
@@ -485,7 +485,7 @@
}
int
-intr_event_schedule_thread(struct intr_event *ie)
+intr_event_schedule_thread_flags(struct intr_event *ie, int flags)
{
struct intr_entropy entropy;
struct intr_thread *it;
@@ -531,7 +531,8 @@
CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
p->p_comm);
TD_CLR_IWAIT(td);
- setrunqueue(td, SRQ_INTR);
+ setrunqueue(td, SRQ_INTR |
+ (flags & IE_FLAG_NOPREEMPT ? SRQ_NOPREEMPT : 0));
} else {
CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d",
__func__, p->p_pid, p->p_comm, it->it_need, td->td_state);
@@ -541,6 +542,13 @@
return (0);
}
+int
+intr_event_schedule_thread(struct intr_event *ie)
+{
+
+ return (intr_event_schedule_thread_flags(ie, 0));
+}
+
/*
* Add a software interrupt handler to a specified event. If a given event
* is not specified, then a new event is created.
@@ -595,7 +603,8 @@
*/
atomic_store_rel_int(&ih->ih_need, 1);
if (!(flags & SWI_DELAY)) {
- error = intr_event_schedule_thread(ie);
+ error = intr_event_schedule_thread_flags(ie,
+ (flags & SWI_NOPREEMPT) ? IE_FLAG_NOPREEMPT : 0);
KASSERT(error == 0, ("stray software interrupt"));
}
}
==== //depot/projects/netsmp/src/sys/kern/sched_4bsd.c#2 (text+ko) ====
@@ -1174,7 +1174,9 @@
}
if (!forwarded) {
- if ((flags & SRQ_YIELDING) == 0 && maybe_preempt(td))
+ if ((flags & SRQ_YIELDING) == 0 &&
+ (flags & SRQ_NOPREEMPT) == 0 &&
+ maybe_preempt(td))
return;
else
maybe_resched(td);
@@ -1214,7 +1216,7 @@
* OURSELF case, we are puting ourself on the run queue
* which also only happens when we are about to yield.
*/
- if((flags & SRQ_YIELDING) == 0) {
+ if ((flags & SRQ_YIELDING) == 0 && (flags & SRQ_NOPREEMPT) == 0) {
if (maybe_preempt(td))
return;
}
==== //depot/projects/netsmp/src/sys/kern/sched_ule.c#6 (text+ko) ====
@@ -1767,7 +1767,7 @@
ke = td->td_kse;
kg = td->td_ksegrp;
canmigrate = 1;
- preemptive = !(flags & SRQ_YIELDING);
+ preemptive = !(flags & SRQ_YIELDING || flags & SRQ_NOPREEMPT);
class = PRI_BASE(kg->kg_pri_class);
kseq = KSEQ_SELF();
if ((ke->ke_flags & KEF_INTERNAL) == 0)
==== //depot/projects/netsmp/src/sys/net/netisr.c#3 (text+ko) ====
@@ -74,6 +74,8 @@
SYSCTL_INT(_debug, OID_AUTO, mpsafenet, CTLFLAG_RD, &debug_mpsafenet, 0,
"Enable/disable MPSAFE network support");
+static int netisr_preempt = 1; /* netisr will preempt when woken. */
+
volatile unsigned int netisr; /* scheduling bits for network */
struct netisr {
@@ -159,7 +161,8 @@
void
legacy_setsoftnet(void)
{
- swi_sched(net_ih, 0);
+
+ swi_sched(net_ih, netisr_preempt ? 0 : SWI_NOPREEMPT);
}
void
@@ -219,6 +222,9 @@
SYSCTL_INT(_net_isr, OID_AUTO, swi_count, CTLFLAG_RD,
&isrstat.isrs_swi_count, 0, "");
+SYSCTL_INT(_net_isr, OID_AUTO, preempt, CTLFLAG_RW,
+ &netisr_preempt, 0, "");
+
/*
* Process all packets currently present in a netisr queue. Used to
* drain an existing set of packets waiting for processing when we
==== //depot/projects/netsmp/src/sys/sys/interrupt.h#4 (text+ko) ====
@@ -81,8 +81,14 @@
#define IE_ENTROPY 0x000002 /* Interrupt is an entropy source. */
#define IE_ADDING_THREAD 0x000004 /* Currently building an ithread. */
+/*
+ * Flags passed to intr_event_schedule_thread_flags().
+ */
+#define IE_FLAG_NOPREEMPT 0x00000001 /* Schedule; don't preempt. */
+
/* Flags to pass to sched_swi. */
#define SWI_DELAY 0x2
+#define SWI_NOPREEMPT 0x4
/*
* Software interrupt numbers in priority order. The priority determines
@@ -121,6 +127,7 @@
int intr_event_destroy(struct intr_event *ie);
int intr_event_remove_handler(void *cookie);
int intr_event_schedule_thread(struct intr_event *ie);
+int intr_event_schedule_thread_flags(struct intr_event *ie, int flags);
int swi_add(struct intr_event **eventp, const char *name,
driver_intr_t handler, void *arg, int pri, enum intr_type flags,
void **cookiep);
==== //depot/projects/netsmp/src/sys/sys/proc.h#5 (text+ko) ====
@@ -685,6 +685,7 @@
#define SRQ_OURSELF 0x0002 /* It is ourself (from mi_switch). */
#define SRQ_INTR 0x0004 /* It is probably urgent. */
#define SRQ_PREEMPTED 0x0008 /* has been preempted.. be kind */
+#define SRQ_NOPREEMPT 0x0010 /* Caller hints not to preempt. */
/* How values for thread_single(). */
#define SINGLE_NO_EXIT 0
More information about the p4-projects
mailing list