tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kernel crash, struct ptimer and callouts
On Mon, Jul 07, 2008 at 04:12:16PM +0000, Christos Zoulas wrote:
> How about this untested patch?
Working version is here [1]. I didn't test virtual and prof clocks, but
they should obviously work.
Appending the patch here for conventience.
[1]: http://koowaldah.org/people/ash/netbsd/ptimer-altfix.diff
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 099b6ba..4bb519a 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -590,9 +590,12 @@ timer_create1(timer_t *tid, clockid_t id, struct sigevent
*evp,
pt->pt_poverruns = 0;
pt->pt_entry = timerid;
pt->pt_queued = false;
- pt->pt_active = 0;
timerclear(&pt->pt_time.it_value);
- callout_init(&pt->pt_ch, 0);
+ if (id == CLOCK_REALTIME)
+ callout_init(&pt->pt_ch, 0);
+ else
+ pt->pt_active = 0;
+
pts->pts_timers[timerid] = pt;
mutex_spin_exit(&timer_lock);
@@ -623,13 +626,16 @@ sys_timer_delete(struct lwp *l, const struct
sys_timer_delete_args *uap,
mutex_spin_exit(&timer_lock);
return (EINVAL);
}
- if (pt->pt_active) {
- ptn = LIST_NEXT(pt, pt_list);
- LIST_REMOVE(pt, pt_list);
- for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list))
- timeradd(&pt->pt_time.it_value, &ptn->pt_time.it_value,
- &ptn->pt_time.it_value);
- pt->pt_active = 0;
+ if (pt->pt_type != CLOCK_REALTIME) {
+ if (pt->pt_active) {
+ ptn = LIST_NEXT(pt, pt_list);
+ LIST_REMOVE(pt, pt_list);
+ for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list))
+ timeradd(&pt->pt_time.it_value,
+ &ptn->pt_time.it_value,
+ &ptn->pt_time.it_value);
+ pt->pt_active = 0;
+ }
}
itimerfree(pts, timerid);
@@ -1088,9 +1094,12 @@ dosetitimer(struct proc *p, int which, struct itimerval
*itvp)
pt->pt_proc = p;
pt->pt_type = which;
pt->pt_entry = which;
- pt->pt_active = 0;
pt->pt_queued = false;
- callout_init(&pt->pt_ch, CALLOUT_MPSAFE);
+ if (pt->pt_type == CLOCK_REALTIME)
+ callout_init(&pt->pt_ch, CALLOUT_MPSAFE);
+ else
+ pt->pt_active = 0;
+
switch (which) {
case ITIMER_REAL:
pt->pt_ev.sigev_signo = SIGALRM;
@@ -1171,10 +1180,13 @@ timers_free(struct proc *p, int which)
timerclear(&tv);
for (ptn = LIST_FIRST(&pts->pts_virtual);
ptn && ptn != pts->pts_timers[ITIMER_VIRTUAL];
- ptn = LIST_NEXT(ptn, pt_list))
+ ptn = LIST_NEXT(ptn, pt_list)) {
+ KASSERT(ptn->pt_type != CLOCK_REALTIME);
timeradd(&tv, &ptn->pt_time.it_value, &tv);
+ }
LIST_FIRST(&pts->pts_virtual) = NULL;
if (ptn) {
+ KASSERT(ptn->pt_type != CLOCK_REALTIME);
timeradd(&tv, &ptn->pt_time.it_value,
&ptn->pt_time.it_value);
LIST_INSERT_HEAD(&pts->pts_virtual, ptn, pt_list);
@@ -1182,10 +1194,13 @@ timers_free(struct proc *p, int which)
timerclear(&tv);
for (ptn = LIST_FIRST(&pts->pts_prof);
ptn && ptn != pts->pts_timers[ITIMER_PROF];
- ptn = LIST_NEXT(ptn, pt_list))
+ ptn = LIST_NEXT(ptn, pt_list)) {
+ KASSERT(ptn->pt_type != CLOCK_REALTIME);
timeradd(&tv, &ptn->pt_time.it_value, &tv);
+ }
LIST_FIRST(&pts->pts_prof) = NULL;
if (ptn) {
+ KASSERT(ptn->pt_type != CLOCK_REALTIME);
timeradd(&tv, &ptn->pt_time.it_value,
&ptn->pt_time.it_value);
LIST_INSERT_HEAD(&pts->pts_prof, ptn, pt_list);
@@ -1221,7 +1236,8 @@ itimerfree(struct ptimers *pts, int index)
else if (pt->pt_queued)
TAILQ_REMOVE(&timer_queue, pt, pt_chain);
mutex_spin_exit(&timer_lock);
- callout_destroy(&pt->pt_ch);
+ if (pt->pt_type == CLOCK_REALTIME)
+ callout_destroy(&pt->pt_ch);
pool_put(&ptimer_pool, pt);
}
Home |
Main Index |
Thread Index |
Old Index