Skip to content

Commit

Permalink
driver core: Fix probe_count imbalance in really_probe()
Browse files Browse the repository at this point in the history
syzbot is reporting hung task in wait_for_device_probe() [1]. At least,
we always need to decrement probe_count if we incremented probe_count in
really_probe().

However, since I can't find "Resources present before probing" message in
the console log, both "this message simply flowed off" and "syzbot is not
hitting this path" will be possible. Therefore, while we are at it, let's
also prepare for concurrent wait_for_device_probe() calls by replacing
wake_up() with wake_up_all().

[1] https://syzkaller.appspot.com/bug?id=25c833f1983c9c1d512f4ff860dd0d7f5a2e2c0f

Reported-by: syzbot <syzbot+805f5f6ae37411f15b64@syzkaller.appspotmail.com>
Fixes: 7c35e69 ("driver core: Print device when resources present in really_probe()")
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: stable <stable@kernel.org>
Link: https://lore.kernel.org/r/20200713021254.3444-1-penguin-kernel@I-love.SAKURA.ne.jp
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Tetsuo Handa authored and gregkh committed Jul 23, 2020
1 parent bf9b82b commit b292b50
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ static void deferred_probe_timeout_work_func(struct work_struct *work)

list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe)
dev_info(private->device, "deferred probe pending\n");
wake_up(&probe_timeout_waitqueue);
wake_up_all(&probe_timeout_waitqueue);
}
static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func);

Expand Down Expand Up @@ -498,7 +498,8 @@ static int really_probe(struct device *dev, struct device_driver *drv)
drv->bus->name, __func__, drv->name, dev_name(dev));
if (!list_empty(&dev->devres_head)) {
dev_crit(dev, "Resources present before probing\n");
return -EBUSY;
ret = -EBUSY;
goto done;
}

re_probe:
Expand Down Expand Up @@ -627,7 +628,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
ret = 0;
done:
atomic_dec(&probe_count);
wake_up(&probe_waitqueue);
wake_up_all(&probe_waitqueue);
return ret;
}

Expand Down

0 comments on commit b292b50

Please sign in to comment.