Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Mar 2009 12:59:20 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        Warner Losh <imp@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r189574 - head/sys/kern
Message-ID:  <200903251259.20921.jhb@freebsd.org>
In-Reply-To: <200903091320.n29DKNT8027311@svn.freebsd.org>
References:  <200903091320.n29DKNT8027311@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Monday 09 March 2009 9:20:23 am Warner Losh wrote:
> Author: imp
> Date: Mon Mar  9 13:20:23 2009
> New Revision: 189574
> URL: http://svn.freebsd.org/changeset/base/189574
> 
> Log:
>   Fix a long-standing bug in newbus.  It was introduced when subclassing
>   was introduced.  If you have a bus, say cardbus, that is derived from
>   a base-bus (say PCI), then ordinarily all PCI drivers would attach to
>   cardbus devices.  However, there had been one exception: kldload
>   wouldn't work.
>   
>   The problem is in devclass_add_driver.  In this routine, all we did
>   was call to the pci device's BUS_DRIVER_ADDED routine.  However, since
>   cardbus bus instances had a different devclass, none of them were
>   called.
>   
> Modified: head/sys/kern/subr_bus.c
> 
==============================================================================
> --- head/sys/kern/subr_bus.c	Mon Mar  9 13:12:48 2009	(r189573)
> +++ head/sys/kern/subr_bus.c	Mon Mar  9 13:20:23 2009	(r189574)
> @@ -82,6 +82,8 @@ struct devclass {
>  	char		*name;
>  	device_t	*devices;	/* array of devices indexed by unit */
>  	int		maxunit;	/* size of devices array */
> +	int		flags;
> +#define DC_HAS_CHILDREN		1
>  
>  	struct sysctl_ctx_list sysctl_ctx;
>  	struct sysctl_oid *sysctl_tree;
> @@ -813,6 +815,7 @@ devclass_find_internal(const char *class
>  	if (parentname && dc && !dc->parent &&
>  	    strcmp(classname, parentname) != 0) {
>  		dc->parent = devclass_find_internal(parentname, NULL, FALSE);
> +		dc->parent->flags |= DC_HAS_CHILDREN;
>  	}
>  
>  	return (dc);

So this is the cause of the recent reports of panics on boot.  The problem is 
that when drivers are registered during boot they are loaded in a "random" 
order (depends on the order the objects are linked actually).  The point, 
though, is that a subclass might register first.  In that case, trying to set 
dc->parent will fail because the parent driver isn't registered yet, so 
dc->parent will be NULL when it tries to set DC_HAS_CHILDREN.  Just not 
setting the flag if dc->parent is NULL will fix the panics, but I think you 
can have baseclasses that won't have DC_HAS_CHILDREN set.  Perhaps the second 
devclass there should always create a devclass (i.e. last param is true)?  
Otherwise dc->parent could be NULL when it shouldn't be, either.  I think 
that is probably the best solution.  I've tested this and it worked.

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903251259.20921.jhb>