Skip to content

Commit

Permalink
async: Fix lack of boot-time console due to insufficient synchronization
Browse files Browse the repository at this point in the history
Our async work synchronization was broken by "async: make sure
independent async domains can't accidentally entangle" (commit
d5a877e), because it would report
the wrong lowest active async ID when there was both running and
pending async work.

This caused things like no being able to read the root filesystem,
resulting in missing console devices and inability to run 'init',
causing a boot-time panic.

This fixes it by properly returning the lowest pending async ID: if
there is any running async work, that will have a lower ID than any
pending work, and we should _not_ look at the pending work list.

There were alternative patches from Jaswinder and James, but this one
also cleans up the code by removing the pointless 'ret' variable and
the unnecesary testing for an empty list around 'for_each_entry()' (if
the list is empty, the for_each_entry() thing just won't execute).

Fixes-bug: http://bugzilla.kernel.org/show_bug.cgi?id=13474
Reported-and-tested-by: Chris Clayton <[email protected]>
Cc: Jaswinder Singh Rajput <[email protected]>
Cc: James Bottomley <[email protected]>
Cc: Arjan van de Ven <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
torvalds committed Jun 8, 2009
1 parent 46056be commit 3af968e
Showing 1 changed file with 5 additions and 10 deletions.
15 changes: 5 additions & 10 deletions kernel/async.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,23 +92,18 @@ extern int initcall_debug;
static async_cookie_t __lowest_in_progress(struct list_head *running)
{
struct async_entry *entry;
async_cookie_t ret = next_cookie; /* begin with "infinity" value */

if (!list_empty(running)) {
entry = list_first_entry(running,
struct async_entry, list);
ret = entry->cookie;
return entry->cookie;
}

if (!list_empty(&async_pending)) {
list_for_each_entry(entry, &async_pending, list)
if (entry->running == running) {
ret = entry->cookie;
break;
}
}
list_for_each_entry(entry, &async_pending, list)
if (entry->running == running)
return entry->cookie;

return ret;
return next_cookie; /* "infinity" value */
}

static async_cookie_t lowest_in_progress(struct list_head *running)
Expand Down

0 comments on commit 3af968e

Please sign in to comment.