13 Mar, 2013

2 commits


26 Jan, 2013

1 commit

  • 9fdb04cdc55 ("async: replace list of active domains with global list
    of pending items") added a struct list_head global_list in struct
    async_entry, which isn't initialised. This means that if
    !domain->registered at __async_schedule(), then list_del_init() will
    be called on the list head in async_run_entry_fn with both pointers
    NULL, causing a crash. This is fixed by initialising both the
    global_list and domain_list list_heads after kzalloc'ing the entry.

    This was noticed due to dapm_power_widgets() which uses
    ASYNC_DOMAIN_EXCLUSIVE, which initialises the domain->registered to 0.

    Signed-off-by: James Hogan
    Signed-off-by: Tejun Heo
    Reported-by: James Hogan
    Reported-by: Stephen Warren

    James Hogan
     

24 Jan, 2013

5 commits

  • Global synchronization - async_synchronize_full() - is currently
    implemented by keeping a list of all active registered domains and
    syncing them one by one until no domain is active.

    While this isn't necessarily a complex scheme, it can easily be
    simplified by keeping global list of the pending items of all
    registered active domains instead of list of domains and simply using
    the globl pending list the same way as domain syncing.

    This patch replaces async_domains with async_global_pending and update
    lowest_in_progress() to use the global pending list if @domain is
    %NULL. async_synchronize_full_domain(NULL) is now allowed and
    equivalent to async_synchronize_full(). As no one is calling with
    NULL domain, this doesn't affect any existing users.

    async_register_mutex is no longer necessary and dropped.

    Signed-off-by: Tejun Heo
    Cc: Arjan van de Ven
    Cc: Dan Williams
    Cc: Linus Torvalds

    Tejun Heo
     
  • Async kept single global pending list and per-domain running lists.
    When an async item is queued, it's put on the global pending list.
    The item is moved to the per-domain running list when its execution
    starts.

    At this point, this design complicates execution and synchronization
    without bringing any benefit. The list only matters for
    synchronization which doesn't care whether a given async item is
    pending or executing. Also, global synchronization is done by
    iterating through all active registered async_domains, so the global
    async_pending list doesn't help anything either.

    Rename async_domain->running to async_domain->pending and put async
    items directly there and remove when execution completes. This
    simplifies lowest_in_progress() a lot - the first item on the pending
    list is the one with the lowest cookie, and async_run_entry_fn()
    doesn't have to mess with moving the item from pending to running.

    After the change, whether a domain is empty or not can be trivially
    determined by looking at async_domain->pending. Remove
    async_domain->count and use list_empty() on pending instead.

    Signed-off-by: Tejun Heo
    Cc: Arjan van de Ven
    Cc: Dan Williams
    Cc: Linus Torvalds

    Tejun Heo
     
  • Currently, next_cookie is used as the infinity value. In most cases,
    this should work fine but it theoretically could bring subtle behavior
    difference between async_synchronize_full() and
    async_synchronize_full_domain().

    async_synchronize_full() keeps waiting until there's no registered
    async_entry left regardless of what next_cookie was when the function
    was called. It guarantees that the queue is completely drained at
    least once before returning.

    However, async_synchronize_full_domain() doesn't. It synchronizes
    upto next_cookie and if further async jobs are queued after the
    next_cookie value to synchronize is decided, they won't be waited for.

    For unrelated async jobs, the behavior difference doesn't matter;
    however, if async jobs which are related (nested or otherwise) to the
    executing ones are queued while sychronization is in progress, the
    resulting behavior difference could be problematic.

    This can be easily fixed by using ULLONG_MAX as the infinity value
    instead. Define ASYNC_COOKIE_MAX as ULLONG_MAX and use it as the
    infinity value for synchronization. This makes
    async_synchronize_full_domain() fully drain the domain at least once
    before returning, making its behavior match async_synchronize_full().

    Signed-off-by: Tejun Heo
    Cc: Arjan van de Ven
    Cc: Dan Williams
    Cc: Linus Torvalds

    Tejun Heo
     
  • In the beginning, running lists were literal struct list_heads. Later
    on, struct async_domain was added. For some reason, while the
    conversion substituted list_heads with async_domains, the variable
    names weren't fully converted. In more places, "running" was used for
    struct async_domain while other places adopted new "domain" name.

    The situation is made much worse by having async_domain's running list
    named "domain" and async_entry's field pointing to async_domain named
    "running".

    So, we end up with mix of "running" and "domain" for variable names
    for async_domain, with the field names of async_domain and async_entry
    swapped between "running" and "domain".

    It feels almost intentionally made to be as confusing as possible.
    Bring some sanity by

    * Renaming all async_domain variables "domain".

    * s/async_running/async_dfl_domain/

    * s/async_domain->domain/async_domain->running/

    * s/async_entry->running/async_entry->domain/

    Signed-off-by: Tejun Heo
    Cc: Arjan van de Ven
    Cc: Dan Williams
    Cc: Linus Torvalds

    Tejun Heo
     
  • To receive f56c3196f251012de9b3ebaff55732a9074fdaae ("async: fix
    __lowest_in_progress()").

    Signed-off-by: Tejun Heo

    Tejun Heo
     

23 Jan, 2013

1 commit

  • Commit 083b804c4d3e ("async: use workqueue for worker pool") made it
    possible that async jobs are moved from pending to running out-of-order.
    While pending async jobs will be queued and dispatched for execution in
    the same order, nothing guarantees they'll enter "1) move self to the
    running queue" of async_run_entry_fn() in the same order.

    Before the conversion, async implemented its own worker pool. An async
    worker, upon being woken up, fetches the first item from the pending
    list, which kept the executing lists sorted. The conversion to
    workqueue was done by adding work_struct to each async_entry and async
    just schedules the work item. The queueing and dispatching of such work
    items are still in order but now each worker thread is associated with a
    specific async_entry and moves that specific async_entry to the
    executing list. So, depending on which worker reaches that point
    earlier, which is non-deterministic, we may end up moving an async_entry
    with larger cookie before one with smaller one.

    This broke __lowest_in_progress(). running->domain may not be properly
    sorted and is not guaranteed to contain lower cookies than pending list
    when not empty. Fix it by ensuring sort-inserting to the running list
    and always looking at both pending and running when trying to determine
    the lowest cookie.

    Over time, the async synchronization implementation became quite messy.
    We better restructure it such that each async_entry is linked to two
    lists - one global and one per domain - and not move it when execution
    starts. There's no reason to distinguish pending and running. They
    behave the same for synchronization purposes.

    Signed-off-by: Tejun Heo
    Cc: Arjan van de Ven
    Cc: stable@vger.kernel.org
    Signed-off-by: Linus Torvalds

    Tejun Heo
     

19 Jan, 2013

1 commit


17 Jan, 2013

1 commit

  • If the default iosched is built as module, the kernel may deadlock
    while trying to load the iosched module on device probe if the probing
    was running off async. This is because async_synchronize_full() at
    the end of module init ends up waiting for the async job which
    initiated the module loading.

    async A modprobe

    1. finds a device
    2. registers the block device
    3. request_module(default iosched)
    4. modprobe in userland
    5. load and init module
    6. async_synchronize_full()

    Async A waits for modprobe to finish in request_module() and modprobe
    waits for async A to finish in async_synchronize_full().

    Because there's no easy to track dependency once control goes out to
    userland, implementing properly nested flushing is difficult. For
    now, make module init perform async_synchronize_full() iff module init
    has queued async jobs as suggested by Linus.

    This avoids the described deadlock because iosched module doesn't use
    async and thus wouldn't invoke async_synchronize_full(). This is
    hacky and incomplete. It will deadlock if async module loading nests;
    however, this works around the known problem case and seems to be the
    best of bad options.

    For more details, please refer to the following thread.

    http://thread.gmane.org/gmane.linux.kernel/1420814

    Signed-off-by: Tejun Heo
    Reported-by: Alex Riesen
    Tested-by: Ming Lei
    Tested-by: Alex Riesen
    Cc: Arjan van de Ven
    Cc: Jens Axboe
    Signed-off-by: Linus Torvalds

    Tejun Heo
     

20 Jul, 2012

2 commits

  • In response to an async related regression James noted:

    "My theory is that this is an init problem: The assumption in a lot of
    our code is that async_synchronize_full() waits for everything ... even
    the domain specific async schedules, which isn't true."

    ...so make this assumption true.

    Each domain, including the default one, registers itself on a global domain
    list when work is scheduled. Once all entries complete it exits that
    list. Waiting for the list to be empty syncs all in-flight work across
    all domains.

    Domains can opt-out of global syncing if they are declared as exclusive
    ASYNC_DOMAIN_EXCLUSIVE(). All stack-based domains have been declared
    exclusive since the domain may go out of scope as soon as the last work
    item completes.

    Statically declared domains are mostly ok, but async_unregister_domain()
    is there to close any theoretical races with pending
    async_synchronize_full waiters at module removal time.

    Signed-off-by: Dan Williams
    Acked-by: Arjan van de Ven
    Reported-by: Meelis Roos
    Reported-by: Eldad Zack
    Tested-by: Eldad Zack
    Signed-off-by: James Bottomley

    Dan Williams
     
  • This is in preparation for teaching async_synchronize_full() to sync all
    pending async work, and not just on the async_running domain. This
    conversion is functionally equivalent, just embedding the existing list
    in a new async_domain type.

    The .registered attribute is used in a later patch to distinguish
    between domains that want to be flushed by async_synchronize_full()
    versus those that only expect async_synchronize_{full|cookie}_domain to
    be used for flushing.

    [jejb: add async.h to scsi_priv.h for struct async_domain]
    Signed-off-by: Dan Williams
    Acked-by: Arjan van de Ven
    Acked-by: Mark Brown
    Tested-by: Eldad Zack
    Signed-off-by: James Bottomley

    Dan Williams
     

13 Jan, 2012

1 commit


31 Oct, 2011

1 commit

  • The changed files were only including linux/module.h for the
    EXPORT_SYMBOL infrastructure, and nothing else. Revector them
    onto the isolated export header for faster compile times.

    Nothing to see here but a whole lot of instances of:

    -#include
    +#include

    This commit is only changing the kernel dir; next targets
    will probably be mm, fs, the arch dirs, etc.

    Signed-off-by: Paul Gortmaker

    Paul Gortmaker
     

15 Sep, 2011

1 commit

  • The variables here are really not used uninitialized.

    kernel/async.c: In function 'async_synchronize_cookie_domain':
    kernel/async.c:270:10: warning: 'starttime.tv64' may be used uninitialized in this function
    kernel/async.c: In function 'async_run_entry_fn':
    kernel/async.c:122:10: warning: 'calltime.tv64' may be used uninitialized in this function

    Signed-off-by: Vitaliy Ivanov
    Signed-off-by: Konstantin Khlebnikov
    Signed-off-by: Viresh Kumar
    Signed-off-by: Jiri Kosina

    Vitaliy Ivanov
     

15 Jun, 2011

1 commit


14 Jul, 2010

1 commit


30 Mar, 2010

1 commit

  • …it slab.h inclusion from percpu.h

    percpu.h is included by sched.h and module.h and thus ends up being
    included when building most .c files. percpu.h includes slab.h which
    in turn includes gfp.h making everything defined by the two files
    universally available and complicating inclusion dependencies.

    percpu.h -> slab.h dependency is about to be removed. Prepare for
    this change by updating users of gfp and slab facilities include those
    headers directly instead of assuming availability. As this conversion
    needs to touch large number of source files, the following script is
    used as the basis of conversion.

    http://userweb.kernel.org/~tj/misc/slabh-sweep.py

    The script does the followings.

    * Scan files for gfp and slab usages and update includes such that
    only the necessary includes are there. ie. if only gfp is used,
    gfp.h, if slab is used, slab.h.

    * When the script inserts a new include, it looks at the include
    blocks and try to put the new include such that its order conforms
    to its surrounding. It's put in the include block which contains
    core kernel includes, in the same order that the rest are ordered -
    alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
    doesn't seem to be any matching order.

    * If the script can't find a place to put a new include (mostly
    because the file doesn't have fitting include block), it prints out
    an error message indicating which .h file needs to be added to the
    file.

    The conversion was done in the following steps.

    1. The initial automatic conversion of all .c files updated slightly
    over 4000 files, deleting around 700 includes and adding ~480 gfp.h
    and ~3000 slab.h inclusions. The script emitted errors for ~400
    files.

    2. Each error was manually checked. Some didn't need the inclusion,
    some needed manual addition while adding it to implementation .h or
    embedding .c file was more appropriate for others. This step added
    inclusions to around 150 files.

    3. The script was run again and the output was compared to the edits
    from #2 to make sure no file was left behind.

    4. Several build tests were done and a couple of problems were fixed.
    e.g. lib/decompress_*.c used malloc/free() wrappers around slab
    APIs requiring slab.h to be added manually.

    5. The script was run on all .h files but without automatically
    editing them as sprinkling gfp.h and slab.h inclusions around .h
    files could easily lead to inclusion dependency hell. Most gfp.h
    inclusion directives were ignored as stuff from gfp.h was usually
    wildly available and often used in preprocessor macros. Each
    slab.h inclusion directive was examined and added manually as
    necessary.

    6. percpu.h was updated not to include slab.h.

    7. Build test were done on the following configurations and failures
    were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
    distributed build env didn't work with gcov compiles) and a few
    more options had to be turned off depending on archs to make things
    build (like ipr on powerpc/64 which failed due to missing writeq).

    * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
    * powerpc and powerpc64 SMP allmodconfig
    * sparc and sparc64 SMP allmodconfig
    * ia64 SMP allmodconfig
    * s390 SMP allmodconfig
    * alpha SMP allmodconfig
    * um on x86_64 SMP allmodconfig

    8. percpu.h modifications were reverted so that it could be applied as
    a separate patch and serve as bisection point.

    Given the fact that I had only a couple of failures from tests on step
    6, I'm fairly confident about the coverage of this conversion patch.
    If there is a breakage, it's likely to be something in one of the arch
    headers which should be easily discoverable easily on most builds of
    the specific arch.

    Signed-off-by: Tejun Heo <tj@kernel.org>
    Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>

    Tejun Heo
     

09 Jun, 2009

1 commit

  • Our async work synchronization was broken by "async: make sure
    independent async domains can't accidentally entangle" (commit
    d5a877e8dd409d8c702986d06485c374b705d340), 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
    Cc: Jaswinder Singh Rajput
    Cc: James Bottomley
    Cc: Arjan van de Ven
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

25 May, 2009

1 commit

  • The problem occurs when async_synchronize_full_domain() is called when
    the async_pending list is not empty. This will cause lowest_running()
    to return the cookie of the first entry on the async_pending list, which
    might be nothing at all to do with the domain being asked for and thus
    cause the domain synchronization to wait for an unrelated domain. This
    can cause a deadlock if domain synchronization is used from one domain
    to wait for another.

    Fix by running over the async_pending list to see if any pending items
    actually belong to our domain (and return their cookies if they do).

    Signed-off-by: James Bottomley
    Signed-off-by: Arjan van de Ven
    Signed-off-by: Linus Torvalds

    James Bottomley
     

29 Mar, 2009

1 commit


09 Feb, 2009

5 commits


06 Feb, 2009

1 commit

  • alpha:

    kernel/async.c: In function 'run_one_entry':
    kernel/async.c:141: warning: format '%lli' expects type 'long long int', but argument 2 has type 'async_cookie_t'
    kernel/async.c:149: warning: format '%lli' expects type 'long long int', but argument 2 has type 'async_cookie_t'
    kernel/async.c:149: warning: format '%lld' expects type 'long long int', but argument 4 has type 's64'
    kernel/async.c: In function 'async_synchronize_cookie_special':
    kernel/async.c:250: warning: format '%lli' expects type 'long long int', but argument 3 has type 's64'

    Cc: Arjan van de Ven
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrew Morton
     

13 Jan, 2009

1 commit

  • At 37000 feet somewhere near Greenland I woke up from a half-sleep with the
    realisation that __lowest_in_progress() is buggy. After landing I checked
    and there were indeed 2 problems with it; this patch fixes both:
    * The order of the list checks was wrong
    * The locking was not correct.

    Signed-off-by: Arjan van de Ven
    Signed-off-by: Linus Torvalds

    Arjan van de Ven
     

10 Jan, 2009

1 commit


09 Jan, 2009

1 commit

  • turns out that there are real problems with allowing async
    tasks that are scheduled from async tasks to run after
    the async_synchronize_full() returns.

    This patch makes the _full more strict and a complete
    synchronization. Later I might need to add back a lighter
    form of synchronization for other uses.. but not right now.

    Signed-off-by: Arjan van de Ven
    Signed-off-by: Linus Torvalds

    Arjan van de Ven
     

08 Jan, 2009

2 commits

  • while tracking the asynchronous calls during boot using the initcall_debug
    convention is useful, doing it once the kernel is done is actually
    bad now that we use asynchronous operations post boot as well...

    Signed-off-by: Arjan van de Ven

    Arjan van de Ven
     
  • Right now, most of the kernel boot is strictly synchronous, such that
    various hardware delays are done sequentially.

    In order to make the kernel boot faster, this patch introduces
    infrastructure to allow doing some of the initialization steps
    asynchronously, which will hide significant portions of the hardware delays
    in practice.

    In order to not change device order and other similar observables, this
    patch does NOT do full parallel initialization.

    Rather, it operates more in the way an out of order CPU does; the work may
    be done out of order and asynchronous, but the observable effects
    (instruction retiring for the CPU) are still done in the original sequence.

    Signed-off-by: Arjan van de Ven

    Arjan van de Ven