From owner-freebsd-stable@FreeBSD.ORG Fri Jul 22 21:58:19 2011 Return-Path: Delivered-To: freebsd-stable@FreeBSD.org Received: from [127.0.0.1] (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by hub.freebsd.org (Postfix) with ESMTP id 28598106566C; Fri, 22 Jul 2011 21:58:17 +0000 (UTC) (envelope-from jkim@FreeBSD.org) From: Jung-uk Kim To: Callum Gibson Date: Fri, 22 Jul 2011 17:57:58 -0400 User-Agent: KMail/1.6.2 References: <20110719112033.GA51765@omma.gibson.athome> <201107211753.42373.jkim@FreeBSD.org> <20110722111305.GB76391@omma.gibson.athome> In-Reply-To: <20110722111305.GB76391@omma.gibson.athome> MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_pJfKOvpaM48NZ7P" Message-Id: <201107221758.01272.jkim@FreeBSD.org> Cc: freebsd-stable@FreeBSD.org, freebsd-amd64@FreeBSD.org Subject: Re: powernow regression in 8-STABLE X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Jul 2011 21:58:19 -0000 --Boundary-00=_pJfKOvpaM48NZ7P Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline On Friday 22 July 2011 07:13 am, Callum Gibson wrote: > On 21Jul11 17:53, Jung-uk Kim wrote: > }> > }> > http://members.optusnet.com.au/callumgibson/boot_verboser_nousb.out > }> and dev.cpu.0.freq reappears! Spooky. Is that a solution or a }> > workaround? I noticed this disables usb keyboard support at the }> > boot menus. > } > }It is a workaround. Please try the attached patch. > > Sorry, no improvement that I can see. See verbose output: > > http://members.optusnet.com.au/callumgibson/boot_verboser2.out Please try the attached patch. If it doesn't work, I need to see "acpidump -dt" output. Jung-uk Kim --Boundary-00=_pJfKOvpaM48NZ7P Content-Type: text/plain; charset="iso-8859-1"; name="kern_cpu3.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kern_cpu3.diff" Index: sys/kern/kern_cpu.c =================================================================== --- sys/kern/kern_cpu.c (revision 224271) +++ sys/kern/kern_cpu.c (working copy) @@ -145,9 +145,7 @@ static int cpufreq_attach(device_t dev) { struct cpufreq_softc *sc; - struct pcpu *pc; device_t parent; - uint64_t rate; int numdevs; CF_DEBUG("initializing %s\n", device_get_nameunit(dev)); @@ -157,18 +155,7 @@ cpufreq_attach(device_t dev) sysctl_ctx_init(&sc->sysctl_ctx); TAILQ_INIT(&sc->all_levels); CF_MTX_INIT(&sc->lock); - sc->curr_level.total_set.freq = CPUFREQ_VAL_UNKNOWN; SLIST_INIT(&sc->saved_freq); - /* Try to get nominal CPU freq to use it as maximum later if needed */ - sc->max_mhz = cpu_get_nominal_mhz(dev); - /* If that fails, try to measure the current rate */ - if (sc->max_mhz <= 0) { - pc = cpu_get_pcpu(dev); - if (cpu_est_clockrate(pc->pc_cpuid, &rate) == 0) - sc->max_mhz = rate / 1000000; - else - sc->max_mhz = CPUFREQ_VAL_UNKNOWN; - } /* * Only initialize one set of sysctls for all CPUs. In the future, @@ -500,6 +487,7 @@ cf_get_method(device_t dev, struct cf_level *level goto out; } } + CF_DEBUG("get freq failed, estimated freq %d\n", (int)rate); error = ENXIO; out: @@ -551,17 +539,23 @@ cf_levels_method(device_t dev, struct cf_level *le * provide settings for informational purposes only. */ error = CPUFREQ_DRV_TYPE(devs[i], &type); - if (error || (type & CPUFREQ_FLAG_INFO_ONLY)) { - if (error == 0) { - CF_DEBUG("skipping info-only driver %s\n", - device_get_nameunit(devs[i])); - } + if (error) continue; - } set_count = MAX_SETTINGS; error = CPUFREQ_DRV_SETTINGS(devs[i], sets, &set_count); if (error || set_count == 0) continue; + if ((type & CPUFREQ_TYPE_MASK) == CPUFREQ_TYPE_ABSOLUTE && + sc->max_mhz < sets[0].freq) { + CF_DEBUG("setting max freq %d from %s\n", + sets[0].freq, device_get_nameunit(devs[i])); + sc->max_mhz = sets[0].freq; + } + if ((type & CPUFREQ_FLAG_INFO_ONLY) != 0) { + CF_DEBUG("skipping info-only driver %s\n", + device_get_nameunit(devs[i])); + continue; + } /* Add the settings to our absolute/relative lists. */ switch (type & CPUFREQ_TYPE_MASK) { @@ -867,8 +861,9 @@ cpufreq_dup_set(struct cpufreq_softc *sc, struct c static int cpufreq_curr_sysctl(SYSCTL_HANDLER_ARGS) { + struct cf_level level; + struct cf_level *levels; struct cpufreq_softc *sc; - struct cf_level *levels; int count, devcount, error, freq, i, n; device_t *devs; @@ -876,10 +871,10 @@ cpufreq_curr_sysctl(SYSCTL_HANDLER_ARGS) sc = oidp->oid_arg1; levels = sc->levels_buf; - error = CPUFREQ_GET(sc->dev, &levels[0]); + error = CPUFREQ_GET(sc->dev, &level); if (error) goto out; - freq = levels[0].total_set.freq; + freq = level.total_set.freq; error = sysctl_handle_int(oidp, &freq, 0, req); if (error != 0 || req->newptr == NULL) goto out; @@ -1000,8 +995,11 @@ out: int cpufreq_register(device_t dev) { + struct cf_setting set; + struct cf_setting *sets; struct cpufreq_softc *sc; device_t cf_dev, cpu_dev; + int error, freq, max, set_count, type; /* Add a sysctl to get each driver's settings separately. */ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), @@ -1009,14 +1007,34 @@ cpufreq_register(device_t dev) OID_AUTO, "freq_settings", CTLTYPE_STRING | CTLFLAG_RD, dev, 0, cpufreq_settings_sysctl, "A", "CPU frequency driver settings"); + /* Get settings from the device and find current and maximum frequencies */ + freq = max = CPUFREQ_VAL_UNKNOWN; + if (CPUFREQ_DRV_TYPE(dev, &type) == 0 && + (type & CPUFREQ_TYPE_MASK) == CPUFREQ_TYPE_ABSOLUTE) { + if (CPUFREQ_DRV_GET(dev, &set) == 0) + freq = set.freq; + set_count = MAX_SETTINGS; + sets = malloc(set_count * sizeof(*sets), M_TEMP, M_NOWAIT); + if (sets != NULL) { + if (CPUFREQ_DRV_SETTINGS(dev, sets, &set_count) == 0 && + set_count > 0) + max = sets[0].freq; + free(sets, M_TEMP); + } + } + /* * Add only one cpufreq device to each CPU. Currently, all CPUs * must offer the same levels and be switched at the same time. */ cpu_dev = device_get_parent(dev); - if ((cf_dev = device_find_child(cpu_dev, "cpufreq", -1))) { + cf_dev = device_find_child(cpu_dev, "cpufreq", -1); + if (cf_dev != NULL) { sc = device_get_softc(cf_dev); - sc->max_mhz = CPUFREQ_VAL_UNKNOWN; + if (sc->curr_level.total_set.freq == CPUFREQ_VAL_UNKNOWN) + sc->curr_level.total_set.freq = freq; + if (sc->max_mhz < max) + sc->max_mhz = max; return (0); } @@ -1025,8 +1043,13 @@ cpufreq_register(device_t dev) if (cf_dev == NULL) return (ENOMEM); device_quiet(cf_dev); - - return (device_probe_and_attach(cf_dev)); + error = device_probe(cf_dev); + if (error) + return (error); + sc = device_get_softc(cf_dev); + sc->curr_level.total_set.freq = freq; + sc->max_mhz = max; + return (device_attach(cf_dev)); } int --Boundary-00=_pJfKOvpaM48NZ7P--