Skip to content

Commit

Permalink
Revert "device core: Remove deprecated create_singlethread_workqueue"
Browse files Browse the repository at this point in the history
This reverts commit 2c507e4 ("device core: Remove deprecated
create_singlethread_workqueue").

This is a temporary fix for qemu-arm hangs on the following command that
schedule_work() triggers (?) dead-lock that nanosleep on hello->main()
never returns.

$ qemu-system-arm -M versatilepb -m 512M -nographic  -serial null \
-semihosting -kernel rumpobj/tests/hello

This should be fixed in a transparent way in a future.

Signed-off-by: Hajime Tazaki <thehajime@gmail.com>
  • Loading branch information
thehajime committed Feb 13, 2017
1 parent f82b294 commit 95be33a
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
static DEFINE_MUTEX(deferred_probe_mutex);
static LIST_HEAD(deferred_probe_pending_list);
static LIST_HEAD(deferred_probe_active_list);
static struct workqueue_struct *deferred_wq;
static atomic_t deferred_trigger_count = ATOMIC_INIT(0);

/*
Expand Down Expand Up @@ -174,7 +175,7 @@ static void driver_deferred_probe_trigger(void)
* Kick the re-probe thread. It may already be scheduled, but it is
* safe to kick it again.
*/
schedule_work(&deferred_probe_work);
queue_work(deferred_wq, &deferred_probe_work);
}

/**
Expand Down Expand Up @@ -210,10 +211,14 @@ void device_unblock_probing(void)
*/
static int deferred_probe_initcall(void)
{
deferred_wq = create_singlethread_workqueue("deferwq");
if (WARN_ON(!deferred_wq))
return -ENOMEM;

driver_deferred_probe_enable = true;
driver_deferred_probe_trigger();
/* Sort as many dependencies as possible before exiting initcalls */
flush_work(&deferred_probe_work);
flush_workqueue(deferred_wq);
return 0;
}
late_initcall(deferred_probe_initcall);
Expand Down Expand Up @@ -477,7 +482,8 @@ int driver_probe_done(void)
void wait_for_device_probe(void)
{
/* wait for the deferred probe workqueue to finish */
flush_work(&deferred_probe_work);
if (driver_deferred_probe_enable)
flush_workqueue(deferred_wq);

/* wait for the known devices to complete their probing */
wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
Expand Down

0 comments on commit 95be33a

Please sign in to comment.