Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F160021544
D1894.id3990.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D1894.id3990.diff
View Options
Index: sys/kern/kern_timeout.c
===================================================================
--- sys/kern/kern_timeout.c
+++ sys/kern/kern_timeout.c
@@ -163,6 +163,7 @@
sbintime_t cc_lastscan;
void *cc_cookie;
u_int cc_bucket;
+ u_int cc_inited;
char cc_ktr_event_name[20];
};
@@ -225,7 +226,6 @@
cc_cce_cleanup(struct callout_cpu *cc, int direct)
{
- cc_exec_curr(cc, direct) = NULL;
cc_exec_cancel(cc, direct) = false;
cc_exec_waiting(cc, direct) = false;
#ifdef SMP
@@ -266,6 +266,7 @@
* XXX: Clip callout to result of previous function of maxusers
* maximum 384. This is still huge, but acceptable.
*/
+ memset(cc_cpu, 0, sizeof(cc_cpu));
ncallout = imin(16 + maxproc + maxfiles, 18508);
TUNABLE_INT_FETCH("kern.ncallout", &ncallout);
@@ -307,6 +308,7 @@
mtx_init(&cc->cc_lock, "callout", NULL, MTX_SPIN | MTX_RECURSE);
SLIST_INIT(&cc->cc_callfree);
+ cc->cc_inited = 1;
cc->cc_callwheel = malloc(sizeof(struct callout_list) * callwheelsize,
M_CALLOUT, M_WAITOK);
for (i = 0; i < callwheelsize; i++)
@@ -313,8 +315,10 @@
LIST_INIT(&cc->cc_callwheel[i]);
TAILQ_INIT(&cc->cc_expireq);
cc->cc_firstevent = SBT_MAX;
- for (i = 0; i < 2; i++)
+ for (i = 0; i < 2; i++) {
+ cc_exec_curr(cc, i) = NULL;
cc_cce_cleanup(cc, i);
+ }
snprintf(cc->cc_ktr_event_name, sizeof(cc->cc_ktr_event_name),
"callwheel cpu %d", cpu);
if (cc->cc_callout == NULL) /* Only cpu0 handles timeout(9) */
@@ -347,6 +351,7 @@
* may be willing to acquire the callout cpu lock.
*/
c->c_cpu = CPUBLOCK;
+ c->l_cpu = new_cpu;
spinlock_enter();
CC_UNLOCK(cc);
new_cc = CC_CPU(new_cpu);
@@ -572,6 +577,16 @@
return (cc);
}
+void
+callout_deactivate(struct callout *c)
+{
+ struct callout_cpu *cc;
+
+ cc = callout_lock(c);
+ c->c_flags &= ~CALLOUT_ACTIVE;
+ CC_UNLOCK(cc);
+}
+
static void
callout_cc_add(struct callout *c, struct callout_cpu *cc,
sbintime_t sbt, sbintime_t precision, void (*func)(void *),
@@ -945,6 +960,17 @@
int cancelled, direct;
cancelled = 0;
+ if ((cpu >= CPUBLOCK) || (cpu < 0)) {
+ /*
+ * Most likely CPUBLOCK was set in c->c_cpu
+ * and this was passed in via macro, fix it
+ * to be the l_cpu we were on.
+ */
+ cpu = c->l_cpu;
+ } else if (cc_cpu[cpu].cc_inited == 0) {
+ /* Invalid CPU spec */
+ cpu = c->l_cpu;
+ }
if (flags & C_ABSOLUTE) {
to_sbt = sbt;
} else {
@@ -998,9 +1024,10 @@
* wrong direct flag if we don't do it before we add.
*/
if (flags & C_DIRECT_EXEC) {
- c->c_flags |= CALLOUT_DIRECT;
+ direct = 1;
+ } else {
+ direct = 0;
}
- direct = (c->c_flags & CALLOUT_DIRECT) != 0;
KASSERT(!direct || c->c_lock == NULL,
("%s: direct callout %p has lock", __func__, c));
cc = callout_lock(c);
@@ -1145,7 +1172,11 @@
}
} else
use_lock = 0;
- direct = (c->c_flags & CALLOUT_DIRECT) != 0;
+ if (c->c_flags & CALLOUT_DIRECT) {
+ direct = 1;
+ } else {
+ direct = 0;
+ }
sq_locked = 0;
old_cc = NULL;
again:
@@ -1281,6 +1312,10 @@
c, c->c_func, c->c_arg);
KASSERT(!cc_cce_migrating(cc, direct),
("callout wrongly scheduled for migration"));
+ if (callout_migrating(c)) {
+ c->c_flags &= ~CALLOUT_DFRMIGRATION;
+ cc_cce_cleanup(cc, direct);
+ }
CC_UNLOCK(cc);
KASSERT(!sq_locked, ("sleepqueue chain locked"));
return (1);
@@ -1294,20 +1329,7 @@
* we return 0.
*/
c->c_flags &= ~CALLOUT_DFRMIGRATION;
-#ifdef SMP
- /*
- * We can't call cc_cce_cleanup here since
- * if we do it will remove .ce_curr and
- * its still running. This will prevent a
- * reschedule of the callout when the
- * execution completes.
- */
- cc_migration_cpu(cc, direct) = CPUBLOCK;
- cc_migration_time(cc, direct) = 0;
- cc_migration_prec(cc, direct) = 0;
- cc_migration_func(cc, direct) = NULL;
- cc_migration_arg(cc, direct) = NULL;
-#endif
+ cc_cce_cleanup(cc, direct);
CTR3(KTR_CALLOUT, "postponing stop %p func %p arg %p",
c, c->c_func, c->c_arg);
CC_UNLOCK(cc);
@@ -1350,7 +1372,7 @@
c->c_lock = &Giant.lock_object;
c->c_flags = 0;
}
- c->c_cpu = timeout_cpu;
+ c->l_cpu = c->c_cpu = timeout_cpu;
}
void
@@ -1366,7 +1388,7 @@
(LC_SPINLOCK | LC_SLEEPABLE)), ("%s: invalid lock class",
__func__));
c->c_flags = flags & (CALLOUT_RETURNUNLOCKED | CALLOUT_SHAREDLOCK);
- c->c_cpu = timeout_cpu;
+ c->l_cpu = c->c_cpu = timeout_cpu;
}
#ifdef APM_FIXUP_CALLTODO
Index: sys/sys/_callout.h
===================================================================
--- sys/sys/_callout.h
+++ sys/sys/_callout.h
@@ -59,6 +59,7 @@
struct lock_object *c_lock; /* lock to handle */
int c_flags; /* state of this entry */
volatile int c_cpu; /* CPU we're scheduled on */
+ volatile int l_cpu; /* CPU we last were on */
};
#endif
Index: sys/sys/callout.h
===================================================================
--- sys/sys/callout.h
+++ sys/sys/callout.h
@@ -65,7 +65,7 @@
#ifdef _KERNEL
#define callout_active(c) ((c)->c_flags & CALLOUT_ACTIVE)
#define callout_migrating(c) ((c)->c_flags & CALLOUT_DFRMIGRATION)
-#define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE)
+void callout_deactivate(struct callout *c);
#define callout_drain(c) _callout_stop_safe(c, 1)
void callout_init(struct callout *, int);
void _callout_init_lock(struct callout *, struct lock_object *, int);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jun 21, 3:51 PM (16 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34153555
Default Alt Text
D1894.id3990.diff (5 KB)
Attached To
Mode
D1894: Guarding against invalid CPU or mixed mode callout_reset and callout_reset_on
Attached
Detach File
Event Timeline
Log In to Comment