Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752018Ab3FWTt1 (ORCPT ); Sun, 23 Jun 2013 15:49:27 -0400 Received: from mail-ie0-f175.google.com ([209.85.223.175]:35652 "EHLO mail-ie0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750879Ab3FWTtX (ORCPT ); Sun, 23 Jun 2013 15:49:23 -0400 MIME-Version: 1.0 In-Reply-To: <1410772.iYNzcAkY0L@vostro.rjw.lan> References: <2737587.I0nULev1kj@vostro.rjw.lan> <15269989.ojxutYs2L1@vostro.rjw.lan> <1410772.iYNzcAkY0L@vostro.rjw.lan> Date: Sun, 23 Jun 2013 12:49:22 -0700 X-Google-Sender-Auth: dSz-hhiLEzsnqqVTp0Jx6t4dUiU Message-ID: Subject: Re: [PATCH 3/3] ACPI / dock / PCI: Synchronous handling of dock events for PCI devices From: Yinghai Lu To: "Rafael J. Wysocki" Cc: ACPI Devel Maling List , Bjorn Helgaas , "Alexander E . Patrakov" , Jiang Liu , Greg Kroah-Hartman , Yijing Wang , Jiang Liu , "linux-pci@vger.kernel.org" , Linux Kernel Mailing List Content-Type: text/plain; charset=ISO-8859-1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3925 Lines: 97 On Sun, Jun 23, 2013 at 2:59 AM, Rafael J. Wysocki wrote: > On Saturday, June 22, 2013 05:22:20 PM Yinghai Lu wrote: >> On Sat, Jun 22, 2013 at 2:25 PM, Rafael J. Wysocki wrote: >> > From: Rafael J. Wysocki >> > >> > To resolve that deadlock use the observation that >> > unregister_hotplug_dock_device() won't need to acquire hp_lock >> > if PCI bridges the devices on the dock station depend on are >> > prevented from being removed prematurely while the first loop in >> > hotplug_dock_devices() is in progress. >> > >> > To make that possible, introduce a mechanism by which the callers of >> > register_hotplug_dock_device() can provide "init" and "release" >> > routines that will be executed, respectively, after the addition >> > and removal of the physical device object associated with the >> > given ACPI device handle. Make acpiphp use two new functions, >> > acpiphp_dock_init() and acpiphp_dock_release(), respectively, >> > calling get_bridge() and put_bridge() on the PCI bridge holding the >> > given device, respectively, for this purpose. >> > >> > In addition to that, remove the dock station's list of >> > "hotplug devices" and make the dock code always walk the whole list >> > of "dependent devices" instead in such a way that the loops in >> > hotplug_dock_devices() and dock_event() (replacing the loops over >> > "hotplug devices") will take references to the list entries that >> > register_hotplug_dock_device() has been called for. That prevents >> > the "release" routines associated with those entries from being >> > called while the given entry is being processed and for PCI >> > devices this means that their bridges won't be removed (by a >> > concurrent thread) while hotplug_event_func() handling them is >> > being executed. >> .. >> > -static void >> > -dock_del_hotplug_device(struct dock_station *ds, >> > - struct dock_dependent_device *dd) >> > +static void dock_release_hotplug(struct dock_dependent_device *dd) >> > { >> > - mutex_lock(&ds->hp_lock); >> > - list_del(&dd->hotplug_list); >> > - mutex_unlock(&ds->hp_lock); >> > + void (*release)(void *) = NULL; >> > + void *context = NULL; >> > + >> > + mutex_lock(&hotplug_lock); >> > + >> > + if (dd->hp_context && !--dd->hp_refcount) { >> > + dd->hp_ops = NULL; >> > + context = dd->hp_context; >> > + dd->hp_context = NULL; >> > + release = dd->hp_release; >> > + dd->hp_release = NULL; >> > + } >> > + >> > + if (release && context) >> > + release(context); >> > + >> > + mutex_unlock(&hotplug_lock); >> > +} >> > + >> > +static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, >> > + bool uevent) >> > +{ >> > + acpi_notify_handler cb = NULL; >> > + bool run = false; >> > + >> > + mutex_lock(&hotplug_lock); >> > + >> > + if (dd->hp_context) { >> > + run = true; >> > + dd->hp_refcount++; >> > + if (dd->hp_ops) >> > + cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler; >> > + } >> > + >> > + mutex_unlock(&hotplug_lock); >> > + >> > + if (!run) >> > + return; >> > + >> > + if (cb) >> > + cb(dd->handle, event, dd->hp_context); >> > + >> > + dock_release_hotplug(dd); >> >> during DOCKING, dock_release_hotplug get called too? > > Yes, we need to drop down the refcount we've just bumped up. > ok, I see. Acked-by: Yinghai Lu -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/