Date: Fri, 23 Jul 2010 16:46:42 +0000 (UTC) From: Andriy Gapon <avg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r210422 - head/sys/kern Message-ID: <201007231646.o6NGkgiv053858@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avg Date: Fri Jul 23 16:46:42 2010 New Revision: 210422 URL: http://svn.freebsd.org/changeset/base/210422 Log: cpufreq: allocate long-lived buffer for handling of sysctl requests At present the cpufreq sysctl handler for current level setting would allocate and deallocate a temporary buffer of 24KB even to handle a read-only query. This puts unnecessary load on memory subsystem when current level is checked frequently, e.g. when the likes of powerd and system monitoring software are running. Change the strategy to allocating a long-lived buffer for handling the requests. Reviewed by: njl MFC after: 2 weeks Modified: head/sys/kern/kern_cpu.c Modified: head/sys/kern/kern_cpu.c ============================================================================== --- head/sys/kern/kern_cpu.c Fri Jul 23 15:32:44 2010 (r210421) +++ head/sys/kern/kern_cpu.c Fri Jul 23 16:46:42 2010 (r210422) @@ -76,6 +76,7 @@ struct cpufreq_softc { device_t dev; struct sysctl_ctx_list sysctl_ctx; struct task startup_task; + struct cf_level *levels_buf; }; struct cf_setting_array { @@ -180,6 +181,8 @@ cpufreq_attach(device_t dev) CF_DEBUG("initializing one-time data for %s\n", device_get_nameunit(dev)); + sc->levels_buf = malloc(CF_MAX_LEVELS * sizeof(*sc->levels_buf), + M_DEVBUF, M_WAITOK); SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(parent)), OID_AUTO, "freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0, @@ -227,6 +230,7 @@ cpufreq_detach(device_t dev) numdevs = devclass_get_count(cpufreq_dc); if (numdevs == 1) { CF_DEBUG("final shutdown for %s\n", device_get_nameunit(dev)); + free(sc->levels_buf, M_DEVBUF); } return (0); @@ -870,9 +874,7 @@ cpufreq_curr_sysctl(SYSCTL_HANDLER_ARGS) devs = NULL; sc = oidp->oid_arg1; - levels = malloc(CF_MAX_LEVELS * sizeof(*levels), M_TEMP, M_NOWAIT); - if (levels == NULL) - return (ENOMEM); + levels = sc->levels_buf; error = CPUFREQ_GET(sc->dev, &levels[0]); if (error) @@ -915,8 +917,6 @@ cpufreq_curr_sysctl(SYSCTL_HANDLER_ARGS) out: if (devs) free(devs, M_TEMP); - if (levels) - free(levels, M_TEMP); return (error); } @@ -934,7 +934,7 @@ cpufreq_levels_sysctl(SYSCTL_HANDLER_ARG /* Get settings from the device and generate the output string. */ count = CF_MAX_LEVELS; - levels = malloc(count * sizeof(*levels), M_TEMP, M_NOWAIT); + levels = sc->levels_buf; if (levels == NULL) { sbuf_delete(&sb); return (ENOMEM); @@ -957,7 +957,6 @@ cpufreq_levels_sysctl(SYSCTL_HANDLER_ARG error = sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req); out: - free(levels, M_TEMP); sbuf_delete(&sb); return (error); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201007231646.o6NGkgiv053858>