Re: device_attach(9) and driver initialization

From: Julian Elischer <julian_at_freebsd.org>
Date: Sat, 07 Apr 2012 14:32:04 -0700
On 4/7/12 5:50 AM, Konstantin Belousov wrote:
> Hello,
> there seems to be a problem with device attach sequence offered by newbus.
> Basically, when device attach method is executing, device is not fully
> initialized yet. Also the device state in the newbus part of the world
> is DS_ALIVE. There is definitely no shattering news in the statements,
> but drivers that e.g. create devfs node to communicate with consumers
> are prone to a race.
>
> If /dev node is created inside device attach method, then usermode
> can start calling cdevsw methods before device fully initialized itself.
> Even more, if device tries to use newbus helpers in cdevsw methods,
> like device_busy(9), then panic occurs "called for unatteched device".
> I get reports from users about this issues, to it is not something
> that only could happen.
Yes, we hit that (the tasting fro geom making requests as soona s we added
the devfs entries came in before we were quite set up) with the fusion-IO
driver but it was "solvable" by moving the device creation to be the very
last thing after all the setup was done. We were prepared to handle 
requests by then.

We don't seem to have hit the device_busy(etc) problem, but your solution
sounds reasonable.

> I propose to add DEVICE_AFTER_ATTACH() driver method, to be called
DEVICE_ATTACH_LATE() or DEVICE_ATTACH_DONE()
> from newbus right after device attach finished and newbus considers
> the device fully initialized. Driver then could create devfs node
> in the after_attach method instead of attach. Please see the patch below.
>
> diff --git a/sys/kern/device_if.m b/sys/kern/device_if.m
> index eb720eb..9db74e2 100644
> --- a/sys/kern/device_if.m
> +++ b/sys/kern/device_if.m
> _at__at_ -43,6 +43,10 _at__at_ INTERFACE device;
>   # Default implementations of some methods.
>   #
>   CODE {
> +	static void null_after_attach(device_t dev)
> +	{
> +	}
> +
>   	static int null_shutdown(device_t dev)
>   	{
>   	    return 0;
> _at__at_ -199,6 +203,21 _at__at_ METHOD int attach {
>   };
>
>   /**
> + * _at_brief Notify the driver that device is in attached state
> + *
> + * Called after driver is successfully attached to the device and
> + * corresponding device_t is fully operational. Driver now may expose
> + * the device to the consumers, e.g. create devfs nodes.
> + *
> + * _at_param dev		the device to probe
> + *
> + * _at_see DEVICE_ATTACH()
> + */
> +METHOD void after_attach {
> +	device_t dev;
> +} DEFAULT null_after_attach;
> +
> +/**
>    * _at_brief Detach a driver from a device.
>    *
>    * This can be called if the user is replacing the
> diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
> index d485b9f..6d849cb 100644
> --- a/sys/kern/subr_bus.c
> +++ b/sys/kern/subr_bus.c
> _at__at_ -2743,6 +2743,7 _at__at_ device_attach(device_t dev)
>   	dev->state = DS_ATTACHED;
>   	dev->flags&= ~DF_DONENOMATCH;
>   	devadded(dev);
> +	DEVICE_AFTER_ATTACH(dev);
>   	return (0);
>   }
>
Received on Sat Apr 07 2012 - 19:31:24 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:25 UTC