Hello Krzysztof, On 16/07/2020 13:32, krzysztof.sobota@xxxxxxxxx wrote: > When watchdog device is being registered, it calls misc_register that > makes watchdog available for systemd to open. This is a data race > scenario, because when device is open it may still have device struct > not initialized - this in turn causes a crash. This patch moves > device initialization before misc_register call and it solves the > problem printed below. [...] thank you for looking into this! > Fixes: 72139dfa2464 ("watchdog: Fix the race between the release of watchdog_core_data and cdev") > Reviewed-by: Guenter Roeck <linux@xxxxxxxxxxxx> Reviewed-by: Alexander Sverdlin <alexander.sverdlin@xxxxxxxxx> > Signed-off-by: Krzysztof Sobota <krzysztof.sobota@xxxxxxxxx> > --- > v1 -> v2: > * removed Change-Id tag > * added Review-by tag > v2 -> v3 > * convert spaces to tabs > * convert (hopefully) mail to plaintext > --- > drivers/watchdog/watchdog_dev.c | 18 +++++++++--------- > 1 file changed, 9 insertions(+), 9 deletions(-) > > diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c > index 10b2090f3e5e..1c322caecf7f 100644 > --- a/drivers/watchdog/watchdog_dev.c > +++ b/drivers/watchdog/watchdog_dev.c > @@ -947,6 +947,15 @@ static int watchdog_cdev_register(struct watchdog_device *wdd) > if (IS_ERR_OR_NULL(watchdog_kworker)) > return -ENODEV; > > + device_initialize(&wd_data->dev); > + wd_data->dev.devt = MKDEV(MAJOR(watchdog_devt), wdd->id); > + wd_data->dev.class = &watchdog_class; > + wd_data->dev.parent = wdd->parent; > + wd_data->dev.groups = wdd->groups; > + wd_data->dev.release = watchdog_core_data_release; > + dev_set_drvdata(&wd_data->dev, wdd); > + dev_set_name(&wd_data->dev, "watchdog%d", wdd->id); > + > kthread_init_work(&wd_data->work, watchdog_ping_work); > hrtimer_init(&wd_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); > wd_data->timer.function = watchdog_timer_expired; > @@ -967,15 +976,6 @@ static int watchdog_cdev_register(struct watchdog_device *wdd) > } > } > > - device_initialize(&wd_data->dev); > - wd_data->dev.devt = MKDEV(MAJOR(watchdog_devt), wdd->id); > - wd_data->dev.class = &watchdog_class; > - wd_data->dev.parent = wdd->parent; > - wd_data->dev.groups = wdd->groups; > - wd_data->dev.release = watchdog_core_data_release; > - dev_set_drvdata(&wd_data->dev, wdd); > - dev_set_name(&wd_data->dev, "watchdog%d", wdd->id); > - > /* Fill in the data structures */ > cdev_init(&wd_data->cdev, &watchdog_fops); > > -- > 2.14.0 > -- Best regards, Alexander Sverdlin.