From owner-freebsd-acpi@FreeBSD.ORG Fri Jun 25 08:31:22 2010 Return-Path: Delivered-To: freebsd-acpi@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7574A1065690; Fri, 25 Jun 2010 08:31:22 +0000 (UTC) (envelope-from avg@freebsd.org) Received: from citadel.icyb.net.ua (citadel.icyb.net.ua [212.40.38.140]) by mx1.freebsd.org (Postfix) with ESMTP id 86F418FC1F; Fri, 25 Jun 2010 08:31:21 +0000 (UTC) Received: from porto.topspin.kiev.ua (porto-e.starpoint.kiev.ua [212.40.38.100]) by citadel.icyb.net.ua (8.8.8p3/ICyb-2.3exp) with ESMTP id LAA19883; Fri, 25 Jun 2010 11:31:19 +0300 (EEST) (envelope-from avg@freebsd.org) Received: from localhost.topspin.kiev.ua ([127.0.0.1]) by porto.topspin.kiev.ua with esmtp (Exim 4.34 (FreeBSD)) id 1OS4Ji-000C3w-LX; Fri, 25 Jun 2010 11:31:18 +0300 Message-ID: <4C246955.9000700@freebsd.org> Date: Fri, 25 Jun 2010 11:31:17 +0300 From: Andriy Gapon User-Agent: Thunderbird 2.0.0.24 (X11/20100603) MIME-Version: 1.0 To: Alexander Motin , freebsd-acpi@freebsd.org References: <4C1E3AE9.3020505@freebsd.org> <4C1E3D44.6020708@FreeBSD.org> <4C1E3FA4.1020009@freebsd.org> In-Reply-To: <4C1E3FA4.1020009@freebsd.org> X-Enigmail-Version: 0.96.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Cc: Subject: Re: cpufreq_curr_sysctl: memory allocation 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: Fri, 25 Jun 2010 08:31:22 -0000 on 20/06/2010 19:19 Andriy Gapon said the following: > I agree, but I hope that a single buffer should be sufficient. > As I understand, all sysctl operate under Giant unless specifically flagged > otherwise. And I don't see any code to explicitly handle concurrent invocations > in cpufreq_curr_sysctl. > My take on it. Seems to work without problems. diff --git a/sys/kern/kern_cpu.c b/sys/kern/kern_cpu.c index 4c4f961..3429a0f 100644 --- a/sys/kern/kern_cpu.c +++ b/sys/kern/kern_cpu.c @@ -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_ARGS) /* 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_ARGS) error = sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req); out: - free(levels, M_TEMP); sbuf_delete(&sb); return (error); } -- Andriy Gapon