From owner-svn-src-head@FreeBSD.ORG Wed Sep 30 17:05:26 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E5A80106566B; Wed, 30 Sep 2009 17:05:26 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D541B8FC08; Wed, 30 Sep 2009 17:05:26 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n8UH5Qwj021040; Wed, 30 Sep 2009 17:05:26 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n8UH5Qi8021038; Wed, 30 Sep 2009 17:05:26 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <200909301705.n8UH5Qi8021038@svn.freebsd.org> From: John Baldwin Date: Wed, 30 Sep 2009 17:05:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r197648 - head/sys/dev/acpica X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Sep 2009 17:05:27 -0000 Author: jhb Date: Wed Sep 30 17:05:26 2009 New Revision: 197648 URL: http://svn.freebsd.org/changeset/base/197648 Log: Split the 'video' ACPI lock up into two locks to resolve a LOR with the sysctl lock. The 'video' lock now protects the 'bus' of video output devices attached to a graphics adapter. It is used when iterating over the list of outputs, etc. The 'video_output' lock is used to lock the output-specific data similar to a driver lock for the individual video outputs. MFC after: 2 weeks Modified: head/sys/dev/acpica/acpi_video.c Modified: head/sys/dev/acpica/acpi_video.c ============================================================================== --- head/sys/dev/acpica/acpi_video.c Wed Sep 30 16:34:50 2009 (r197647) +++ head/sys/dev/acpica/acpi_video.c Wed Sep 30 17:05:26 2009 (r197648) @@ -170,7 +170,13 @@ static struct sysctl_oid *acpi_video_sys static struct acpi_video_output_queue crt_units, tv_units, ext_units, lcd_units, other_units; +/* + * The 'video' lock protects the hierarchy of video output devices + * (the video "bus"). The 'video_output' lock protects per-output + * data is equivalent to a softc lock for each video output. + */ ACPI_SERIAL_DECL(video, "ACPI video"); +ACPI_SERIAL_DECL(video_output, "ACPI video output"); MALLOC_DEFINE(M_ACPIVIDEO, "acpivideo", "ACPI video extension"); static int @@ -236,12 +242,14 @@ acpi_video_attach(device_t dev) acpi_sc = devclass_get_softc(devclass_find("acpi"), 0); if (acpi_sc == NULL) return (ENXIO); + ACPI_SERIAL_BEGIN(video); if (acpi_video_sysctl_tree == NULL) { acpi_video_sysctl_tree = SYSCTL_ADD_NODE(&acpi_video_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "video", CTLFLAG_RD, 0, "video extension control"); } + ACPI_SERIAL_END(video); sc->device = dev; sc->handle = acpi_get_handle(dev); @@ -316,6 +324,7 @@ acpi_video_notify_handler(ACPI_HANDLE ha dss_p = 0; lasthand = NULL; ACPI_SERIAL_BEGIN(video); + ACPI_SERIAL_BEGIN(video_output); STAILQ_FOREACH(vo, &sc->vid_outputs, vo_next) { dss = vo_get_graphics_state(vo->handle); dcs = vo_get_device_status(vo->handle); @@ -331,6 +340,7 @@ acpi_video_notify_handler(ACPI_HANDLE ha } if (lasthand != NULL) vo_set_device_state(lasthand, dss_p|DSS_COMMIT); + ACPI_SERIAL_END(video_output); ACPI_SERIAL_END(video); break; case VID_NOTIFY_REPROBE: @@ -367,12 +377,14 @@ acpi_video_power_profile(void *context) return; ACPI_SERIAL_BEGIN(video); + ACPI_SERIAL_BEGIN(video_output); STAILQ_FOREACH(vo, &sc->vid_outputs, vo_next) { if (vo->vo_levels != NULL && vo->vo_brightness == -1) vo_set_brightness(vo->handle, state == POWER_PROFILE_ECONOMY ? vo->vo_economy : vo->vo_fullpower); } + ACPI_SERIAL_END(video_output); ACPI_SERIAL_END(video); } @@ -550,7 +562,7 @@ static void acpi_video_vo_bind(struct acpi_video_output *vo, ACPI_HANDLE handle) { - ACPI_SERIAL_ASSERT(video); + ACPI_SERIAL_BEGIN(video_output); if (vo->vo_levels != NULL) AcpiOsFree(vo->vo_levels); vo->handle = handle; @@ -565,6 +577,7 @@ acpi_video_vo_bind(struct acpi_video_out /* XXX - see above. */ vo->vo_economy = vo->vo_levels[BCL_ECONOMY]; } + ACPI_SERIAL_END(video_output); } static void @@ -605,7 +618,7 @@ acpi_video_vo_check_level(struct acpi_vi { int i; - ACPI_SERIAL_ASSERT(video); + ACPI_SERIAL_ASSERT(video_output); if (vo->vo_levels == NULL) return (ENODEV); for (i = 0; i < vo->vo_numlevels; i++) @@ -624,7 +637,7 @@ acpi_video_vo_active_sysctl(SYSCTL_HANDL vo = (struct acpi_video_output *)arg1; if (vo->handle == NULL) return (ENXIO); - ACPI_SERIAL_BEGIN(video); + ACPI_SERIAL_BEGIN(video_output); state = (vo_get_device_status(vo->handle) & DCS_ACTIVE) ? 1 : 0; err = sysctl_handle_int(oidp, &state, 0, req); if (err != 0 || req->newptr == NULL) @@ -632,7 +645,7 @@ acpi_video_vo_active_sysctl(SYSCTL_HANDL vo_set_device_state(vo->handle, DSS_COMMIT | (state ? DSS_ACTIVE : DSS_INACTIVE)); out: - ACPI_SERIAL_END(video); + ACPI_SERIAL_END(video_output); return (err); } @@ -644,7 +657,7 @@ acpi_video_vo_bright_sysctl(SYSCTL_HANDL int level, preset, err; vo = (struct acpi_video_output *)arg1; - ACPI_SERIAL_BEGIN(video); + ACPI_SERIAL_BEGIN(video_output); if (vo->handle == NULL) { err = ENXIO; goto out; @@ -674,7 +687,7 @@ acpi_video_vo_bright_sysctl(SYSCTL_HANDL vo_set_brightness(vo->handle, (level == -1) ? preset : level); out: - ACPI_SERIAL_END(video); + ACPI_SERIAL_END(video_output); return (err); } @@ -686,7 +699,7 @@ acpi_video_vo_presets_sysctl(SYSCTL_HAND err = 0; vo = (struct acpi_video_output *)arg1; - ACPI_SERIAL_BEGIN(video); + ACPI_SERIAL_BEGIN(video_output); if (vo->handle == NULL) { err = ENXIO; goto out; @@ -717,7 +730,7 @@ acpi_video_vo_presets_sysctl(SYSCTL_HAND *preset = level; out: - ACPI_SERIAL_END(video); + ACPI_SERIAL_END(video_output); return (err); } @@ -729,7 +742,7 @@ acpi_video_vo_levels_sysctl(SYSCTL_HANDL int err; vo = (struct acpi_video_output *)arg1; - ACPI_SERIAL_BEGIN(video); + ACPI_SERIAL_BEGIN(video_output); if (vo->vo_levels == NULL) { err = ENODEV; goto out; @@ -742,7 +755,7 @@ acpi_video_vo_levels_sysctl(SYSCTL_HANDL vo->vo_numlevels * sizeof(*vo->vo_levels), req); out: - ACPI_SERIAL_END(video); + ACPI_SERIAL_END(video_output); return (err); } @@ -892,6 +905,7 @@ vo_set_brightness(ACPI_HANDLE handle, in { ACPI_STATUS status; + ACPI_SERIAL_ASSERT(video_output); status = acpi_SetInteger(handle, "_BCM", level); if (ACPI_FAILURE(status)) printf("can't evaluate %s._BCM - %s\n", @@ -904,6 +918,7 @@ vo_get_device_status(ACPI_HANDLE handle) UINT32 dcs; ACPI_STATUS status; + ACPI_SERIAL_ASSERT(video_output); dcs = 0; status = acpi_GetInteger(handle, "_DCS", &dcs); if (ACPI_FAILURE(status)) @@ -933,6 +948,7 @@ vo_set_device_state(ACPI_HANDLE handle, { ACPI_STATUS status; + ACPI_SERIAL_ASSERT(video_output); status = acpi_SetInteger(handle, "_DSS", state); if (ACPI_FAILURE(status)) printf("can't evaluate %s._DSS - %s\n",