From owner-freebsd-new-bus@FreeBSD.ORG Fri Jan 6 19:01:12 2006 Return-Path: X-Original-To: new-bus@freebsd.org Delivered-To: freebsd-new-bus@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A0CE716A41F; Fri, 6 Jan 2006 19:01:12 +0000 (GMT) (envelope-from john@baldwin.cx) Received: from speedfactory.net (mail6.speedfactory.net [66.23.216.219]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7E40043D7F; Fri, 6 Jan 2006 19:01:09 +0000 (GMT) (envelope-from john@baldwin.cx) Received: from server.baldwin.cx (unverified [66.23.211.162]) by speedfactory.net (SurgeMail 3.5b3) with ESMTP id 5445766 for multiple; Fri, 06 Jan 2006 14:02:37 -0500 Received: from localhost (john@localhost [127.0.0.1]) by server.baldwin.cx (8.13.4/8.13.4) with ESMTP id k06J164r025983; Fri, 6 Jan 2006 14:01:07 -0500 (EST) (envelope-from john@baldwin.cx) From: John Baldwin To: new-bus@freebsd.org Date: Fri, 6 Jan 2006 14:01:56 -0500 User-Agent: KMail/1.8.2 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200601061401.57308.john@baldwin.cx> X-Virus-Scanned: ClamAV 0.87.1/1234/Fri Jan 6 08:54:31 2006 on server.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-1.4 required=4.2 tests=ALL_TRUSTED autolearn=failed version=3.1.0 X-Spam-Checker-Version: SpamAssassin 3.1.0 (2005-09-13) on server.baldwin.cx X-Server: High Performance Mail Server - http://surgemail.com r=1653887525 Cc: dfr@freebsd.org Subject: Patch to prevent cycles in the devclass tree X-BeenThere: freebsd-new-bus@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD's new-bus architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 06 Jan 2006 19:01:12 -0000 I have been doing some work recently to make the ACPI and OFW (OpenFirmware) PCI bus drivers inherit from the PCI bus driver. As part of this I've run into an issue because the subclass drivers (ACPI PCI and OFW PCI) use the same name "pci" as the superclass. They do this so that they can override the superclass when a "pci" device is added as a child of a "pcib" device. The problem I ran into is that when the subclass was registered, it called devclass_find_internal() with the parentname set to "pci". This caused the "pci" devclass to set its dc->parent member to point to itself. Thus, if in device_probe_child() we didn't find a suitable driver in the first pass of the for loop, we'd keep looping forever and hang during boot. This is the fix I'm currently using but I was curious about feedback on it. It only checks to make sure the a devclass doesn't add itself as a parent, it doesn't walk up hierarchy to avoid a cycle completely: --- //depot/vendor/freebsd/src/sys/kern/subr_bus.c 2005/10/04 22:25:30 +++ //depot/user/jhb/acpipci/kern/subr_bus.c 2006/01/04 21:32:26 @@ -781,7 +781,17 @@ bus_data_generation_update(); } - if (parentname && dc && !dc->parent) { + + /* + * If a parent class is specified, then set that as our parent so + * that this devclass will support drivers for the parent class as + * well. If the parent class has the same name don't do this though + * as it creates a cycle that can trigger an infinite loop in + * device_probe_child() if a device exists for which there is no + * suitable driver. + */ + if (parentname && dc && !dc->parent && + strcmp(classname, parentname) != 0) { dc->parent = devclass_find_internal(parentname, 0, FALSE); } @@ -1240,6 +1250,7 @@ void devclass_set_parent(devclass_t dc, devclass_t pdc) { + KASSERT(dc != pdc, ("%s: loop", __func__)); dc->parent = pdc; } The other possible direction is to rename the subclasses to not use the same name ("pci"), but doing that actually involves a fair bit of work as it means teaching the various pcib drivers to create acpi_pci child devices rather than pci child devices, etc. -- John Baldwin <>< http://www.baldwin.cx/~john/ "Power Users Use the Power to Serve" = http://www.FreeBSD.org