From owner-freebsd-acpi@FreeBSD.ORG Wed Aug 17 17:20:59 2005 Return-Path: X-Original-To: acpi@freebsd.org Delivered-To: freebsd-acpi@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 88E6116A41F for ; Wed, 17 Aug 2005 17:20:59 +0000 (GMT) (envelope-from ume@mahoroba.org) Received: from ameno.mahoroba.org (gw4.mahoroba.org [218.45.22.175]) by mx1.FreeBSD.org (Postfix) with ESMTP id EA04A43D49 for ; Wed, 17 Aug 2005 17:20:58 +0000 (GMT) (envelope-from ume@mahoroba.org) Received: from kasuga.mahoroba.org (IDENT:TgEn3oYWUVaNgtbGhfXk8WE0/6X0MOHC4JvqBYjsYTi1naeDsaOSZD8uMw0ddMna@[IPv6:3ffe:501:185b:801a:20b:97ff:fe2e:b521]) (user=ume mech=CRAM-MD5 bits=0) by ameno.mahoroba.org (8.13.3/8.13.3) with ESMTP/inet6 id j7HHKnMs055887 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 18 Aug 2005 02:20:52 +0900 (JST) (envelope-from ume@mahoroba.org) Date: Thu, 18 Aug 2005 02:20:35 +0900 Message-ID: From: Hajimu UMEMOTO To: Nate Lawson In-Reply-To: References: <20050814023842.C0D845D07@ptavv.es.net> <4300C5DF.40409@root.org> <43013C90.7040901@root.org> <4302298F.6080407@root.org> User-Agent: xcite1.38> Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.7 (=?ISO-8859-4?Q?Sanj=F2?=) APEL/10.6 Emacs/22.0.50 (i386-unknown-freebsd6.0) MULE/5.0 (SAKAKI) X-Operating-System: FreeBSD 6.0-BETA2 X-PGP-Key: http://www.imasy.or.jp/~ume/publickey.asc X-PGP-Fingerprint: 1F00 0B9E 2164 70FC 6DC5 BF5F 04E9 F086 BF90 71FE Organization: Internet Mutual Aid Society, YOKOHAMA MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0 (ameno.mahoroba.org [IPv6:3ffe:501:185b:8010::1]); Thu, 18 Aug 2005 02:20:55 +0900 (JST) X-Virus-Scanned: by amavisd-new X-Virus-Status: Clean X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.0.4 X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on ameno.mahoroba.org Cc: acpi@freebsd.org Subject: Re: Annoyances with passive thermal code (acpi_thermal) X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Aug 2005 17:20:59 -0000 Hi, >>>>> On Wed, 17 Aug 2005 05:10:42 +0900 >>>>> Hajimu UMEMOTO said: > In anyway, we should make this as stack some day. nate> That would be nice for the future. ume> Okay, I'll implement this when I have a time. How about this? The original code allowed to restore a cpu level from CPUFREQ_SET(NULL, prio) with any prio. I tought it is not intentional. So, I changed to check if prio is at same one. Index: sys/kern/kern_cpu.c diff -u -p sys/kern/kern_cpu.c.orig sys/kern/kern_cpu.c --- sys/kern/kern_cpu.c.orig Tue Aug 16 14:22:10 2005 +++ sys/kern/kern_cpu.c Wed Aug 17 12:37:24 2005 @@ -57,12 +57,17 @@ __FBSDID("$FreeBSD: src/sys/kern/kern_cp */ #define CF_MAX_LEVELS 64 +struct cf_saved_freq { + struct cf_level level; + int priority; + SLIST_ENTRY(cf_saved_freq) link; +}; + struct cpufreq_softc { struct sx lock; struct cf_level curr_level; int curr_priority; - struct cf_level saved_level; - int saved_priority; + SLIST_HEAD(, cf_saved_freq) saved_freq; struct cf_level_lst all_levels; int all_count; int max_mhz; @@ -149,7 +154,7 @@ cpufreq_attach(device_t dev) TAILQ_INIT(&sc->all_levels); CF_MTX_INIT(&sc->lock); sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN; - sc->saved_level.total_set.freq = CPUFREQ_VAL_UNKNOWN; + SLIST_INIT(&sc->saved_freq); sc->max_mhz = CPUFREQ_VAL_UNKNOWN; /* @@ -181,12 +186,18 @@ static int cpufreq_detach(device_t dev) { struct cpufreq_softc *sc; + struct cf_saved_freq *saved_freq; int numdevs; CF_DEBUG("shutdown %s\n", device_get_nameunit(dev)); sc = device_get_softc(dev); sysctl_ctx_free(&sc->sysctl_ctx); + while ((saved_freq = SLIST_FIRST(&sc->saved_freq)) != NULL) { + SLIST_REMOVE_HEAD(&sc->saved_freq, link); + free(saved_freq, M_TEMP); + } + /* Only clean up these resources when the last device is detaching. */ numdevs = devclass_get_count(cpufreq_dc); if (numdevs == 1) { @@ -208,12 +219,14 @@ cf_set_method(device_t dev, const struct { struct cpufreq_softc *sc; const struct cf_setting *set; + struct cf_saved_freq *saved_freq, *curr_freq; struct pcpu *pc; int cpu_id, error, i; sc = device_get_softc(dev); error = 0; set = NULL; + saved_freq = NULL; /* * Check that the TSC isn't being used as a timecounter. @@ -223,29 +236,34 @@ cf_set_method(device_t dev, const struct if (strcmp(timecounter->tc_name, "TSC") == 0) return (EBUSY); + CF_MTX_LOCK(&sc->lock); + + /* + * If the requested level has a lower priority, don't allow + * the new level right now. + */ + if (priority < sc->curr_priority) { + CF_DEBUG("ignoring, curr prio %d less than %d\n", priority, + sc->curr_priority); + error = EPERM; + goto out; + } + /* * If the caller didn't specify a level and one is saved, prepare to * restore the saved level. If none has been saved, return an error. - * If they did specify one, but the requested level has a lower - * priority, don't allow the new level right now. */ - CF_MTX_LOCK(&sc->lock); if (level == NULL) { - if (sc->saved_level.total_set.freq != CPUFREQ_VAL_UNKNOWN) { - level = &sc->saved_level; - priority = sc->saved_priority; - CF_DEBUG("restoring saved level, freq %d prio %d\n", - level->total_set.freq, priority); - } else { + saved_freq = SLIST_FIRST(&sc->saved_freq); + if (saved_freq == NULL) { CF_DEBUG("NULL level, no saved level\n"); error = ENXIO; goto out; } - } else if (priority < sc->curr_priority) { - CF_DEBUG("ignoring, curr prio %d less than %d\n", priority, - sc->curr_priority); - error = EPERM; - goto out; + level = &saved_freq->level; + priority = saved_freq->priority; + CF_DEBUG("restoring saved level, freq %d prio %d\n", + level->total_set.freq, priority); } /* Reject levels that are below our specified threshold. */ @@ -322,28 +340,34 @@ cf_set_method(device_t dev, const struct } } - /* If we were restoring a saved state, reset it to "unused". */ - if (level == &sc->saved_level) { - CF_DEBUG("resetting saved level\n"); - sc->saved_level.total_set.freq = CPUFREQ_VAL_UNKNOWN; - sc->saved_priority = 0; - } - /* * Before recording the current level, check if we're going to a - * higher priority and have not saved a level yet. If so, save the - * previous level and priority. + * higher priority. If so, save the previous level and priority. */ if (sc->curr_level.total_set.freq != CPUFREQ_VAL_UNKNOWN && - sc->saved_level.total_set.freq == CPUFREQ_VAL_UNKNOWN && - priority > CPUFREQ_PRIO_USER && priority > sc->curr_priority) { + priority > sc->curr_priority) { CF_DEBUG("saving level, freq %d prio %d\n", sc->curr_level.total_set.freq, sc->curr_priority); - sc->saved_level = sc->curr_level; - sc->saved_priority = sc->curr_priority; + curr_freq = malloc(sizeof(*curr_freq), M_TEMP, M_NOWAIT); + if (curr_freq == NULL) { + error = ENOMEM; + goto out; + } + curr_freq->level = sc->curr_level; + curr_freq->priority = sc->curr_priority; + SLIST_INSERT_HEAD(&sc->saved_freq, curr_freq, link); } sc->curr_level = *level; sc->curr_priority = priority; + + /* If we were restoring a saved state, reset it to "unused". */ + if (saved_freq != NULL) { + CF_DEBUG("resetting saved level\n"); + sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN; + SLIST_REMOVE_HEAD(&sc->saved_freq, link); + free(saved_freq, M_TEMP); + } + error = 0; out: Sincerely, -- Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan ume@mahoroba.org ume@{,jp.}FreeBSD.org http://www.imasy.org/~ume/