From owner-cvs-all Mon Oct 19 10:09:53 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id KAA24802 for cvs-all-outgoing; Mon, 19 Oct 1998 10:09:53 -0700 (PDT) (envelope-from owner-cvs-all@FreeBSD.ORG) Received: from critter.freebsd.dk (critter.freebsd.dk [212.242.40.131]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id KAA24792; Mon, 19 Oct 1998 10:09:46 -0700 (PDT) (envelope-from phk@critter.freebsd.dk) Received: from critter.freebsd.dk (localhost [127.0.0.1]) by critter.freebsd.dk (8.9.1/8.8.5) with ESMTP id TAA19789; Mon, 19 Oct 1998 19:07:41 +0200 (CEST) To: Matthew Dillon cc: Bruce Evans , cvs-all@FreeBSD.ORG, cvs-committers@FreeBSD.ORG Subject: Re: Here's another odd one: 'cputime exceeded' when no cpu limit set In-reply-to: Your message of "Mon, 19 Oct 1998 09:47:19 PDT." <199810191647.JAA16488@apollo.backplane.com> Date: Mon, 19 Oct 1998 19:07:39 +0200 Message-ID: <19787.908816859@critter.freebsd.dk> From: Poul-Henning Kamp Sender: owner-cvs-all@FreeBSD.ORG Precedence: bulk In message <199810191647.JAA16488@apollo.backplane.com>, Matthew Dillon writes: >apollo:/usr/src/sys# fgrep vm_page_flag_clear */*.c >Cputime limit exceeded > > I added debug code to the kernel. In calcru() I added: > > if (totusec < 0) { > /* XXX no %qd in kernel. Truncate. */ > printf("calcru: negative time of %ld usec for pid %d (%s)\n", > (long)totusec, p->p_pid, p->p_comm); > totusec = 0; > } > > And whenever I get Cputime limit exceeded, the following > kernel message is logged: > >calcru: negative time of -21451087 usec for pid 16447 (fgrep) Please try this patch, and set the "NTIMECOUNTER" to something large (10 or so ?) and if that solves your problem, scale it back to where it comes back. I intend this patch to go in anyway, so any and all testing results will be welcome. Poul-Henning Index: i386/isa/clock.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/clock.c,v retrieving revision 1.127 diff -u -r1.127 clock.c --- clock.c 1998/09/20 19:56:28 1.127 +++ clock.c 1998/10/18 11:14:06 @@ -173,7 +173,7 @@ static unsigned tsc_get_timecount __P((struct timecounter *tc)); static void set_timer_freq(u_int freq, int intr_freq); -static struct timecounter tsc_timecounter[3] = { +static struct timecounter tsc_timecounter = { tsc_get_timecount, /* get_timecount */ 0, /* no poll_pps */ ~0u, /* counter_mask */ @@ -182,9 +182,9 @@ }; SYSCTL_OPAQUE(_debug, OID_AUTO, tsc_timecounter, CTLFLAG_RD, - tsc_timecounter, sizeof(tsc_timecounter), "S,timecounter", ""); + &tsc_timecounter, sizeof(tsc_timecounter), "S,timecounter", ""); -static struct timecounter i8254_timecounter[3] = { +static struct timecounter i8254_timecounter = { i8254_get_timecount, /* get_timecount */ 0, /* no poll_pps */ ~0u, /* counter_mask */ @@ -193,7 +193,7 @@ }; SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, - i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", ""); + &i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", ""); static void clkintr(struct clockframe frame) @@ -751,8 +751,8 @@ } set_timer_freq(timer_freq, hz); - i8254_timecounter[0].tc_frequency = timer_freq; - init_timecounter(i8254_timecounter); + i8254_timecounter.tc_frequency = timer_freq; + init_timecounter(&i8254_timecounter); #ifndef CLK_USE_TSC_CALIBRATION if (tsc_freq != 0) { @@ -801,8 +801,8 @@ #endif /* NAPM > 0 */ if (tsc_present && tsc_freq != 0) { - tsc_timecounter[0].tc_frequency = tsc_freq; - init_timecounter(tsc_timecounter); + tsc_timecounter.tc_frequency = tsc_freq; + init_timecounter(&tsc_timecounter); } #endif /* !defined(SMP) */ @@ -1118,7 +1118,7 @@ if (timer0_state != RELEASED) return (EBUSY); /* too much trouble to handle */ set_timer_freq(freq, hz); - i8254_timecounter[0].tc_frequency = freq; + i8254_timecounter.tc_frequency = freq; } return (error); } @@ -1138,7 +1138,7 @@ error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req); if (error == 0 && req->newptr != NULL) { tsc_freq = freq; - tsc_timecounter[0].tc_frequency = tsc_freq; + tsc_timecounter.tc_frequency = tsc_freq; } return (error); } Index: i386/isa/loran.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/loran.c,v retrieving revision 1.8 diff -u -r1.8 loran.c --- loran.c 1998/08/17 19:09:36 1.8 +++ loran.c 1998/10/18 11:11:11 @@ -267,7 +267,7 @@ init_tgc(); - init_timecounter(loran_timecounter); + init_timecounter(&loran_timecounter); TAILQ_INIT(&qdone); TAILQ_INIT(&qready); @@ -557,7 +557,7 @@ return (count); } -static struct timecounter loran_timecounter[3] = { +static struct timecounter loran_timecounter = { loran_get_timecount, /* get_timecount */ 0, /* no pps_poll */ 0xffff, /* counter_mask */ Index: kern/kern_clock.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_clock.c,v retrieving revision 1.80 diff -u -r1.80 kern_clock.c --- kern_clock.c 1998/10/06 23:17:44 1.80 +++ kern_clock.c 1998/10/18 11:55:40 @@ -1,5 +1,3 @@ -static volatile int print_tci = 1; - /*- * Copyright (c) 1997, 1998 Poul-Henning Kamp * Copyright (c) 1982, 1986, 1991, 1993 @@ -48,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +67,16 @@ #include #endif +/* + * Number of timecounters used to implement stable storage + */ +#ifndef NTIMECOUNTER +#define NTIMECOUNTER 2 +#endif + +static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter", + "Timecounter stable storage"); + static void initclocks __P((void *dummy)); SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL) @@ -87,11 +96,32 @@ long tk_nout; long tk_rawcc; -struct timecounter *timecounter; - time_t time_second; /* + * Implement a dummy timecounter which we can use until we get a real one + * in the air. This allows the console and other early stuff to use + * timeservices. + */ + +static unsigned +dummy_get_timecount(struct timecounter *tc) +{ + static unsigned now; + return (++now); +} + +static struct timecounter dummy_timecounter = { + dummy_get_timecount, + 0, + ~0u, + 1000000, + "dummy" +}; + +struct timecounter *timecounter = &dummy_timecounter; + +/* * Clock handling routines. * * This code is written to operate with two timers that run independently of @@ -634,32 +664,28 @@ init_timecounter(struct timecounter *tc) { struct timespec ts0, ts1; + struct timecounter *t1, *t2, *t3; int i; tc->tc_adjustment = 0; tco_setscales(tc); tc->tc_offset_count = tc->tc_get_timecount(tc); - tc[0].tc_tweak = &tc[0]; - tc[2] = tc[1] = tc[0]; - tc[1].tc_other = &tc[2]; - tc[2].tc_other = &tc[1]; - if (!timecounter || !strcmp(timecounter->tc_name, "dummy")) - timecounter = &tc[2]; - tc = &tc[1]; + tc->tc_tweak = tc; + MALLOC(t1, struct timecounter *, sizeof *t1, M_TIMECOUNTER, M_WAITOK); + *t1 = *tc; + t2 = t1; + for (i = 1; i < NTIMECOUNTER; i++) { + MALLOC(t3, struct timecounter *, sizeof *t3, + M_TIMECOUNTER, M_WAITOK); + *t3 = *tc; + t3->tc_other = t2; + t2 = t3; + } + t1->tc_other = t3; + tc = t1; - /* - * Figure out the cost of calling this timecounter. - */ - nanotime(&ts0); - for (i = 0; i < 256; i ++) - tc->tc_get_timecount(tc); - nanotime(&ts1); - ts1.tv_sec -= ts0.tv_sec; - tc->tc_cost = ts1.tv_sec * 1000000000 + ts1.tv_nsec - ts0.tv_nsec; - tc->tc_cost >>= 8; - if (print_tci && strcmp(tc->tc_name, "dummy")) - printf("Timecounter \"%s\" frequency %lu Hz cost %u ns\n", - tc->tc_name, (u_long)tc->tc_frequency, tc->tc_cost); + printf("Timecounter \"%s\" frequency %lu Hz\n", + tc->tc_name, (u_long)tc->tc_frequency); /* XXX: For now always start using the counter. */ tc->tc_offset_count = tc->tc_get_timecount(tc); @@ -804,34 +830,3 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, adjustment, CTLTYPE_INT | CTLFLAG_RW, 0, sizeof(int), sysctl_kern_timecounter_adjustment, "I", ""); - -/* - * Implement a dummy timecounter which we can use until we get a real one - * in the air. This allows the console and other early stuff to use - * timeservices. - */ - -static unsigned -dummy_get_timecount(struct timecounter *tc) -{ - static unsigned now; - return (++now); -} - -static struct timecounter dummy_timecounter[3] = { - { - dummy_get_timecount, - 0, - ~0u, - 1000000, - "dummy" - } -}; - -static void -initdummytimecounter(void *dummy) -{ - init_timecounter(dummy_timecounter); -} - -SYSINIT(dummytc, SI_SUB_CONSOLE, SI_ORDER_FIRST, initdummytimecounter, NULL) Index: sys/time.h =================================================================== RCS file: /home/ncvs/src/sys/sys/time.h,v retrieving revision 1.33 diff -u -r1.33 time.h --- time.h 1998/06/09 13:10:54 1.33 +++ time.h 1998/10/18 11:36:10 @@ -139,7 +139,6 @@ char *tc_name; void *tc_priv; /* These fields will be managed by the generic code. */ - int tc_cost; int32_t tc_adjustment; u_int32_t tc_scale_micro; u_int32_t tc_scale_nano_i; -- Poul-Henning Kamp FreeBSD coreteam member phk@FreeBSD.ORG "Real hackers run -current on their laptop." "ttyv0" -- What UNIX calls a $20K state-of-the-art, 3D, hi-res color terminal To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe cvs-all" in the body of the message