Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Oct 1998 19:07:39 +0200
From:      Poul-Henning Kamp <phk@critter.freebsd.dk>
To:        Matthew Dillon <dillon@apollo.backplane.com>
Cc:        Bruce Evans <bde@zeta.org.au>, cvs-all@FreeBSD.ORG, cvs-committers@FreeBSD.ORG
Subject:   Re: Here's another odd one: 'cputime exceeded' when no cpu limit set 
Message-ID:  <19787.908816859@critter.freebsd.dk>
In-Reply-To: Your message of "Mon, 19 Oct 1998 09:47:19 PDT." <199810191647.JAA16488@apollo.backplane.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
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 <phk@FreeBSD.org>
  * Copyright (c) 1982, 1986, 1991, 1993
@@ -48,6 +46,7 @@
 #include <sys/callout.h>
 #include <sys/kernel.h>
 #include <sys/proc.h>
+#include <sys/malloc.h>
 #include <sys/resourcevar.h>
 #include <sys/signalvar.h>
 #include <sys/timex.h>
@@ -68,6 +67,16 @@
 #include <machine/smp.h>
 #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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19787.908816859>