08 Aug, 2010

1 commit

  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq: (55 commits)
    workqueue: mark init_workqueues() as early_initcall()
    workqueue: explain for_each_*cwq_cpu() iterators
    fscache: fix build on !CONFIG_SYSCTL
    slow-work: kill it
    gfs2: use workqueue instead of slow-work
    drm: use workqueue instead of slow-work
    cifs: use workqueue instead of slow-work
    fscache: drop references to slow-work
    fscache: convert operation to use workqueue instead of slow-work
    fscache: convert object to use workqueue instead of slow-work
    workqueue: fix how cpu number is stored in work->data
    workqueue: fix mayday_mask handling on UP
    workqueue: fix build problem on !CONFIG_SMP
    workqueue: fix locking in retry path of maybe_create_worker()
    async: use workqueue for worker pool
    workqueue: remove WQ_SINGLE_CPU and use WQ_UNBOUND instead
    workqueue: implement unbound workqueue
    workqueue: prepare for WQ_UNBOUND implementation
    libata: take advantage of cmwq and remove concurrency limitations
    workqueue: fix worker management invocation without pending works
    ...

    Fixed up conflicts in fs/cifs/* as per Tejun. Other trivial conflicts in
    include/linux/workqueue.h, kernel/trace/Kconfig and kernel/workqueue.c

    Linus Torvalds
     

01 Aug, 2010

1 commit

  • Mark init_workqueues() as early_initcall() and thus it will be initialized
    before smp bringup. init_workqueues() registers for the hotcpu notifier
    and thus it should cope with the processors that are brought online after
    the workqueues are initialized.

    x86 smp bringup code uses workqueues and uses a workaround for the
    cold boot process (as the workqueues are initialized post smp_init()).
    Marking init_workqueues() as early_initcall() will pave the way for
    cleaning up this code.

    Signed-off-by: Suresh Siddha
    Signed-off-by: Tejun Heo
    Cc: Oleg Nesterov
    Cc: Andrew Morton

    Suresh Siddha
     

23 Jul, 2010

1 commit

  • Once a work starts execution, its data contains the cpu number it was
    on instead of pointing to cwq. This is added by commit 7a22ad75
    (workqueue: carry cpu number in work data once execution starts) to
    reliably determine the work was last on even if the workqueue itself
    was destroyed inbetween.

    Whether data points to a cwq or contains a cpu number was
    distinguished by comparing the value against PAGE_OFFSET. The
    assumption was that a cpu number should be below PAGE_OFFSET while a
    pointer to cwq should be above it. However, on architectures which
    use separate address spaces for user and kernel spaces, this doesn't
    hold as PAGE_OFFSET is zero.

    Fix it by using an explicit flag, WORK_STRUCT_CWQ, to mark what the
    data field contains. If the flag is set, it's pointing to a cwq;
    otherwise, it contains a cpu number.

    Reported on s390 and microblaze during linux-next testing.

    Signed-off-by: Tejun Heo
    Reported-by: Sachin Sant
    Reported-by: Michal Simek
    Reported-by: Martin Schwidefsky
    Tested-by: Martin Schwidefsky
    Tested-by: Michal Simek

    Tejun Heo
     

02 Jul, 2010

3 commits

  • WQ_SINGLE_CPU combined with @max_active of 1 is used to achieve full
    ordering among works queued to a workqueue. The same can be achieved
    using WQ_UNBOUND as unbound workqueues always use the gcwq for
    WORK_CPU_UNBOUND. As @max_active is always one and benefits from cpu
    locality isn't accessible anyway, serving them with unbound workqueues
    should be fine.

    Drop WQ_SINGLE_CPU support and use WQ_UNBOUND instead. Note that most
    single thread workqueue users will be converted to use multithread or
    non-reentrant instead and only the ones which require strict ordering
    will keep using WQ_UNBOUND + @max_active of 1.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • This patch implements unbound workqueue which can be specified with
    WQ_UNBOUND flag on creation. An unbound workqueue has the following
    properties.

    * It uses a dedicated gcwq with a pseudo CPU number WORK_CPU_UNBOUND.
    This gcwq is always online and disassociated.

    * Workers are not bound to any CPU and not concurrency managed. Works
    are dispatched to workers as soon as possible and the only applied
    limitation is @max_active. IOW, all unbound workqeueues are
    implicitly high priority.

    Unbound workqueues can be used as simple execution context provider.
    Contexts unbound to any cpu are served as soon as possible.

    Signed-off-by: Tejun Heo
    Cc: Arjan van de Ven
    Cc: David Howells

    Tejun Heo
     
  • In preparation of WQ_UNBOUND addition, make the following changes.

    * Add WORK_CPU_* constants for pseudo cpu id numbers used (currently
    only WORK_CPU_NONE) and use them instead of NR_CPUS. This is to
    allow another pseudo cpu id for unbound cpu.

    * Reorder WQ_* flags.

    * Make workqueue_struct->cpu_wq a union which contains a percpu
    pointer, regular pointer and an unsigned long value and use
    kzalloc/kfree() in UP allocation path. This will be used to
    implement unbound workqueues which will use only one cwq on SMPs.

    * Move alloc_cwqs() allocation after initialization of wq fields, so
    that alloc_cwqs() has access to wq->flags.

    * Trivial relocation of wq local variables in freeze functions.

    These changes don't cause any functional change.

    Signed-off-by: Tejun Heo

    Tejun Heo
     

29 Jun, 2010

18 commits

  • This patch implements cpu intensive workqueue which can be specified
    with WQ_CPU_INTENSIVE flag on creation. Works queued to a cpu
    intensive workqueue don't participate in concurrency management. IOW,
    it doesn't contribute to gcwq->nr_running and thus doesn't delay
    excution of other works.

    Note that although cpu intensive works won't delay other works, they
    can be delayed by other works. Combine with WQ_HIGHPRI to avoid being
    delayed by other works too.

    As the name suggests this is useful when using workqueue for cpu
    intensive works. Workers executing cpu intensive works are not
    considered for workqueue concurrency management and left for the
    scheduler to manage.

    Signed-off-by: Tejun Heo
    Cc: Andrew Morton

    Tejun Heo
     
  • This patch implements high priority workqueue which can be specified
    with WQ_HIGHPRI flag on creation. A high priority workqueue has the
    following properties.

    * A work queued to it is queued at the head of the worklist of the
    respective gcwq after other highpri works, while normal works are
    always appended at the end.

    * As long as there are highpri works on gcwq->worklist,
    [__]need_more_worker() remains %true and process_one_work() wakes up
    another worker before it start executing a work.

    The above two properties guarantee that works queued to high priority
    workqueues are dispatched to workers and start execution as soon as
    possible regardless of the state of other works.

    Signed-off-by: Tejun Heo
    Cc: Andi Kleen
    Cc: Andrew Morton

    Tejun Heo
     
  • Implement the following utility APIs.

    workqueue_set_max_active() : adjust max_active of a wq
    workqueue_congested() : test whether a wq is contested
    work_cpu() : determine the last / current cpu of a work
    work_busy() : query whether a work is busy

    * Anton Blanchard fixed missing ret initialization in work_busy().

    Signed-off-by: Tejun Heo
    Cc: Anton Blanchard

    Tejun Heo
     
  • This patch makes changes to make new workqueue features available to
    its users.

    * Now that workqueue is more featureful, there should be a public
    workqueue creation function which takes paramters to control them.
    Rename __create_workqueue() to alloc_workqueue() and make 0
    max_active mean WQ_DFL_ACTIVE. In the long run, all
    create_workqueue_*() will be converted over to alloc_workqueue().

    * To further unify access interface, rename keventd_wq to system_wq
    and export it.

    * Add system_long_wq and system_nrt_wq. The former is to host long
    running works separately (so that flush_scheduled_work() dosen't
    take so long) and the latter guarantees any queued work item is
    never executed in parallel by multiple CPUs. These will be used by
    future patches to update workqueue users.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • Define WQ_MAX_ACTIVE and create keventd with max_active set to half of
    it which means that keventd now can process upto WQ_MAX_ACTIVE / 2 - 1
    works concurrently. Unless some combination can result in dependency
    loop longer than max_active, deadlock won't happen and thus it's
    unnecessary to check whether current_is_keventd() before trying to
    schedule a work. Kill current_is_keventd().

    (Lockdep annotations are broken. We need lock_map_acquire_read_norecurse())

    Signed-off-by: Tejun Heo
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: Christoph Lameter
    Cc: Tony Luck
    Cc: Andi Kleen
    Cc: Oleg Nesterov

    Tejun Heo
     
  • Instead of creating a worker for each cwq and putting it into the
    shared pool, manage per-cpu workers dynamically.

    Works aren't supposed to be cpu cycle hogs and maintaining just enough
    concurrency to prevent work processing from stalling due to lack of
    processing context is optimal. gcwq keeps the number of concurrent
    active workers to minimum but no less. As long as there's one or more
    running workers on the cpu, no new worker is scheduled so that works
    can be processed in batch as much as possible but when the last
    running worker blocks, gcwq immediately schedules new worker so that
    the cpu doesn't sit idle while there are works to be processed.

    gcwq always keeps at least single idle worker around. When a new
    worker is necessary and the worker is the last idle one, the worker
    assumes the role of "manager" and manages the worker pool -
    ie. creates another worker. Forward-progress is guaranteed by having
    dedicated rescue workers for workqueues which may be necessary while
    creating a new worker. When the manager is having problem creating a
    new worker, mayday timer activates and rescue workers are summoned to
    the cpu and execute works which might be necessary to create new
    workers.

    Trustee is expanded to serve the role of manager while a CPU is being
    taken down and stays down. As no new works are supposed to be queued
    on a dead cpu, it just needs to drain all the existing ones. Trustee
    continues to try to create new workers and summon rescuers as long as
    there are pending works. If the CPU is brought back up while the
    trustee is still trying to drain the gcwq from the previous offlining,
    the trustee will kill all idles ones and tell workers which are still
    busy to rebind to the cpu, and pass control over to gcwq which assumes
    the manager role as necessary.

    Concurrency managed worker pool reduces the number of workers
    drastically. Only workers which are necessary to keep the processing
    going are created and kept. Also, it reduces cache footprint by
    avoiding unnecessarily switching contexts between different workers.

    Please note that this patch does not increase max_active of any
    workqueue. All workqueues can still only process one work per cpu.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • With gcwq managing all the workers and work->data pointing to the last
    gcwq it was on, non-reentrance can be easily implemented by checking
    whether the work is still running on the previous gcwq on queueing.
    Implement it.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • To implement non-reentrant workqueue, the last gcwq a work was
    executed on must be reliably obtainable as long as the work structure
    is valid even if the previous workqueue has been destroyed.

    To achieve this, work->data will be overloaded to carry the last cpu
    number once execution starts so that the previous gcwq can be located
    reliably. This means that cwq can't be obtained from work after
    execution starts but only gcwq.

    Implement set_work_{cwq|cpu}(), get_work_[g]cwq() and
    clear_work_data() to set work data to the cpu number when starting
    execution, access the overloaded work data and clear it after
    cancellation.

    queue_delayed_work_on() is updated to preserve the last cpu while
    in-flight in timer and other callers which depended on getting cwq
    from work after execution starts are converted to depend on gcwq
    instead.

    * Anton Blanchard fixed compile error on powerpc due to missing
    linux/threads.h include.

    Signed-off-by: Tejun Heo
    Cc: Anton Blanchard

    Tejun Heo
     
  • Reimplement st (single thread) workqueue so that it's friendly to
    shared worker pool. It was originally implemented by confining st
    workqueues to use cwq of a fixed cpu and always having a worker for
    the cpu. This implementation isn't very friendly to shared worker
    pool and suboptimal in that it ends up crossing cpu boundaries often.

    Reimplement st workqueue using dynamic single cpu binding and
    cwq->limit. WQ_SINGLE_THREAD is replaced with WQ_SINGLE_CPU. In a
    single cpu workqueue, at most single cwq is bound to the wq at any
    given time. Arbitration is done using atomic accesses to
    wq->single_cpu when queueing a work. Once bound, the binding stays
    till the workqueue is drained.

    Note that the binding is never broken while a workqueue is frozen.
    This is because idle cwqs may have works waiting in delayed_works
    queue while frozen. On thaw, the cwq is restarted if there are any
    delayed works or unbound otherwise.

    When combined with max_active limit of 1, single cpu workqueue has
    exactly the same execution properties as the original single thread
    workqueue while allowing sharing of per-cpu workers.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • Currently, workqueue freezing is implemented by marking the worker
    freezeable and calling try_to_freeze() from dispatch loop.
    Reimplement it using cwq->limit so that the workqueue is frozen
    instead of the worker.

    * workqueue_struct->saved_max_active is added which stores the
    specified max_active on initialization.

    * On freeze, all cwq->max_active's are quenched to zero. Freezing is
    complete when nr_active on all cwqs reach zero.

    * On thaw, all cwq->max_active's are restored to wq->saved_max_active
    and the worklist is repopulated.

    This new implementation allows having single shared pool of workers
    per cpu.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • Add cwq->nr_active, cwq->max_active and cwq->delayed_work. nr_active
    counts the number of active works per cwq. A work is active if it's
    flushable (colored) and is on cwq's worklist. If nr_active reaches
    max_active, new works are queued on cwq->delayed_work and activated
    later as works on the cwq complete and decrement nr_active.

    cwq->max_active can be specified via the new @max_active parameter to
    __create_workqueue() and is set to 1 for all workqueues for now. As
    each cwq has only single worker now, this double queueing doesn't
    cause any behavior difference visible to its users.

    This will be used to reimplement freeze/thaw and implement shared
    worker pool.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • A work is linked to the next one by having WORK_STRUCT_LINKED bit set
    and these links can be chained. When a linked work is dispatched to a
    worker, all linked works are dispatched to the worker's newly added
    ->scheduled queue and processed back-to-back.

    Currently, as there's only single worker per cwq, having linked works
    doesn't make any visible behavior difference. This change is to
    prepare for multiple shared workers per cpu.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • Reimplement workqueue flushing using color coded works. wq has the
    current work color which is painted on the works being issued via
    cwqs. Flushing a workqueue is achieved by advancing the current work
    colors of cwqs and waiting for all the works which have any of the
    previous colors to drain.

    Currently there are 16 possible colors, one is reserved for no color
    and 15 colors are useable allowing 14 concurrent flushes. When color
    space gets full, flush attempts are batched up and processed together
    when color frees up, so even with many concurrent flushers, the new
    implementation won't build up huge queue of flushers which has to be
    processed one after another.

    Only works which are queued via __queue_work() are colored. Works
    which are directly put on queue using insert_work() use NO_COLOR and
    don't participate in workqueue flushing. Currently only works used
    for work-specific flush fall in this category.

    This new implementation leaves only cleanup_workqueue_thread() as the
    user of flush_cpu_workqueue(). Just make its users use
    flush_workqueue() and kthread_stop() directly and kill
    cleanup_workqueue_thread(). As workqueue flushing doesn't use barrier
    request anymore, the comment describing the complex synchronization
    around it in cleanup_workqueue_thread() is removed together with the
    function.

    This new implementation is to allow having and sharing multiple
    workers per cpu.

    Please note that one more bit is reserved for a future work flag by
    this patch. This is to avoid shifting bits and updating comments
    later.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • work->data field is used for two purposes. It points to cwq it's
    queued on and the lower bits are used for flags. Currently, two bits
    are reserved which is always safe as 4 byte alignment is guaranteed on
    every architecture. However, future changes will need more flag bits.

    On SMP, the percpu allocator is capable of honoring larger alignment
    (there are other users which depend on it) and larger alignment works
    just fine. On UP, percpu allocator is a thin wrapper around
    kzalloc/kfree() and don't honor alignment request.

    This patch introduces WORK_STRUCT_FLAG_BITS and implements
    alloc/free_cwqs() which guarantees max(1 << WORK_STRUCT_FLAG_BITS,
    __alignof__(unsigned long long) alignment both on SMP and UP. On SMP,
    simply wrapping percpu allocator is enough. On UP, extra space is
    allocated so that cwq can be aligned and the original pointer can be
    stored after it which is used in the free path.

    * Alignment problem on UP is reported by Michal Simek.

    Signed-off-by: Tejun Heo
    Cc: Christoph Lameter
    Cc: Ingo Molnar
    Cc: Frederic Weisbecker
    Reported-by: Michal Simek

    Tejun Heo
     
  • Work flags are about to see more traditional mask handling. Define
    WORK_STRUCT_*_BIT as the bit position constant and redefine
    WORK_STRUCT_* as bit masks. Also, make WORK_STRUCT_STATIC_* flags
    conditional

    While at it, re-define these constants as enums and use
    WORK_STRUCT_STATIC instead of hard-coding 2 in
    WORK_DATA_STATIC_INIT().

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • Currently, __create_workqueue_key() takes @singlethread and
    @freezeable paramters and store them separately in workqueue_struct.
    Merge them into a single flags parameter and field and use
    WQ_FREEZEABLE and WQ_SINGLE_THREAD.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • Make the following updates in preparation of concurrency managed
    workqueue. None of these changes causes any visible behavior
    difference.

    * Add comments and adjust indentations to data structures and several
    functions.

    * Rename wq_per_cpu() to get_cwq() and swap the position of two
    parameters for consistency. Convert a direct per_cpu_ptr() access
    to wq->cpu_wq to get_cwq().

    * Add work_static() and Update set_wq_data() such that it sets the
    flags part to WORK_STRUCT_PENDING | WORK_STRUCT_STATIC if static |
    @extra_flags.

    * Move santiy check on work->entry emptiness from queue_work_on() to
    __queue_work() which all queueing paths share.

    * Make __queue_work() take @cpu and @wq instead of @cwq.

    * Restructure flush_work() and __create_workqueue_key() to make them
    easier to modify.

    Signed-off-by: Tejun Heo

    Tejun Heo
     
  • With stop_machine() converted to use cpu_stop, RT workqueue doesn't
    have any user left. Kill RT workqueue support.

    Signed-off-by: Tejun Heo

    Tejun Heo
     

15 Jun, 2010

1 commit

  • Some recent uses of RCU make use of workqueues. In these uses, execution
    within the context of a specific workqueue takes the place of the usual
    RCU read-side primitives such as rcu_read_lock(), and flushing of workqueues
    takes the place of the usual RCU grace-period primitives. Checking for
    correct use of rcu_dereference() in such cases requires a test of whether
    the code is executing in the context of a particular workqueue. This
    commit adds an in_workqueue_context() function that provides this test.
    This new function is only defined when lockdep is enabled, which allows
    it to be used as the second argument of rcu_dereference_check().

    Signed-off-by: Paul E. McKenney

    Paul E. McKenney
     

16 Nov, 2009

1 commit


15 Oct, 2009

1 commit


21 Sep, 2009

1 commit


06 Sep, 2009

1 commit

  • cancel_delayed_work() has to use del_timer_sync() to guarantee the timer
    function is not running after return. But most users doesn't actually
    need this, and del_timer_sync() has problems: it is not useable from
    interrupt, and it depends on every lock which could be taken from irq.

    Introduce __cancel_delayed_work() which calls del_timer() instead.

    The immediate reason for this patch is
    http://bugzilla.kernel.org/show_bug.cgi?id=13757
    but hopefully this helper makes sense anyway.

    As for 13757 bug, actually we need requeue_delayed_work(), but its
    semantics are not yet clear.

    Merge this patch early to resolves cross-tree interdependencies between
    input and infiniband.

    Signed-off-by: Oleg Nesterov
    Cc: Dmitry Torokhov
    Cc: Roland Dreier
    Cc: Stefan Richter
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Oleg Nesterov
     

03 Apr, 2009

1 commit

  • It is a fairly common operation to have a pointer to a work and to need a
    pointer to the delayed work it is contained in. In particular, all
    delayed works which want to rearm themselves will have to do that. So it
    would seem fair to offer a helper function for this operation.

    [akpm@linux-foundation.org: coding-style fixes]
    Signed-off-by: Jean Delvare
    Acked-by: Ingo Molnar
    Cc: "David S. Miller"
    Cc: Herbert Xu
    Cc: Benjamin Herrenschmidt
    Cc: Martin Schwidefsky
    Cc: Greg KH
    Cc: Pekka Enberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jean Delvare
     

27 Jan, 2009

1 commit

  • …/git/tip/linux-2.6-tip

    * 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
    debugobjects: add and use INIT_WORK_ON_STACK
    rcu: remove duplicate CONFIG_RCU_CPU_STALL_DETECTOR
    relay: fix lock imbalance in relay_late_setup_files
    oprofile: fix uninitialized use of struct op_entry
    rcu: move Kconfig menu
    softlock: fix false panic which can occur if softlockup_thresh is reduced
    rcu: add __cpuinit to rcu_init_percpu_data()

    Linus Torvalds
     

22 Jan, 2009

1 commit


12 Jan, 2009

1 commit

  • Alexander Beregalov reported that this warning is caused by the HPET code:

    > hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0
    > hpet0: 3 comparators, 64-bit 14.318180 MHz counter
    > ODEBUG: object is on stack, but not annotated
    > ------------[ cut here ]------------
    > WARNING: at lib/debugobjects.c:251 __debug_object_init+0x2a4/0x352()

    > Bisected down to 26afe5f2fbf06ea0765aaa316640c4dd472310c0
    > (x86: HPET_MSI Initialise per-cpu HPET timers)

    The commit is fine - but the on-stack workqueue entry needs annotation.

    Reported-and-bisected-by: Alexander Beregalov
    Signed-off-by: Peter Zijlstra
    Tested-by: Alexander Beregalov
    Signed-off-by: Ingo Molnar

    Peter Zijlstra
     

06 Nov, 2008

1 commit

  • Impact: introduce new APIs

    We want to deprecate cpumasks on the stack, as we are headed for
    gynormous numbers of CPUs. Eventually, we want to head towards an
    undefined 'struct cpumask' so they can never be declared on stack.

    1) New cpumask functions which take pointers instead of copies.
    (cpus_* -> cpumask_*)

    2) Several new helpers to reduce requirements for temporary cpumasks
    (cpumask_first_and, cpumask_next_and, cpumask_any_and)

    3) Helpers for declaring cpumasks on or offstack for large NR_CPUS
    (cpumask_var_t, alloc_cpumask_var and free_cpumask_var)

    4) 'struct cpumask' for explicitness and to mark new-style code.

    5) Make iterator functions stop at nr_cpu_ids (a runtime constant),
    not NR_CPUS for time efficiency and for smaller dynamic allocations
    in future.

    6) cpumask_copy() so we can allocate less than a full cpumask eventually
    (for alloc_cpumask_var), and so we can eliminate the 'struct cpumask'
    definition eventually.

    7) work_on_cpu() helper for doing task on a CPU, rather than saving old
    cpumask for current thread and manipulating it.

    8) smp_call_function_many() which is smp_call_function_mask() except
    taking a cpumask pointer.

    Note that this patch simply introduces the new functions and leaves
    the obsolescent ones in place. This is to simplify the transition
    patches.

    Signed-off-by: Rusty Russell
    Signed-off-by: Ingo Molnar

    Rusty Russell
     

22 Oct, 2008

1 commit

  • create_rt_workqueue will create a real time prioritized workqueue.
    This is needed for the conversion of stop_machine to a workqueue based
    implementation.
    This patch adds yet another parameter to __create_workqueue_key to tell
    it that we want an rt workqueue.
    However it looks like we rather should have something like "int type"
    instead of singlethread, freezable and rt.

    Signed-off-by: Heiko Carstens
    Signed-off-by: Rusty Russell
    Cc: Ingo Molnar

    Heiko Carstens
     

26 Jul, 2008

1 commit

  • Most of users of flush_workqueue() can be changed to use cancel_work_sync(),
    but sometimes we really need to wait for the completion and cancelling is not
    an option. schedule_on_each_cpu() is good example.

    Add the new helper, flush_work(work), which waits for the completion of the
    specific work_struct. More precisely, it "flushes" the result of of the last
    queue_work() which is visible to the caller.

    For example, this code

    queue_work(wq, work);
    /* WINDOW */
    queue_work(wq, work);

    flush_work(work);

    doesn't necessary work "as expected". What can happen in the WINDOW above is

    - wq starts the execution of work->func()

    - the caller migrates to another CPU

    now, after the 2nd queue_work() this work is active on the previous CPU, and
    at the same time it is queued on another. In this case flush_work(work) may
    return before the first work->func() completes.

    It is trivial to add another helper

    int flush_work_sync(struct work_struct *work)
    {
    return flush_work(work) || wait_on_work(work);
    }

    which works "more correctly", but it has to iterate over all CPUs and thus
    it much slower than flush_work().

    Signed-off-by: Oleg Nesterov
    Acked-by: Max Krasnyansky
    Acked-by: Jarek Poplawski
    Cc: Peter Zijlstra
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Oleg Nesterov
     

25 Jul, 2008

1 commit

  • This interface allows adding a job on a specific cpu.

    Although a work struct on a cpu will be scheduled to other cpu if the cpu
    dies, there is a recursion if a work task tries to offline the cpu it's
    running on. we need to schedule the task to a specific cpu in this case.
    http://bugzilla.kernel.org/show_bug.cgi?id=10897

    [oleg@tv-sign.ru: cleanups]
    Signed-off-by: Zhang Rui
    Tested-by: Rus
    Signed-off-by: Rafael J. Wysocki
    Acked-by: Pavel Machek
    Signed-off-by: Oleg Nesterov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Zhang Rui
     

14 Feb, 2008

1 commit


16 Jan, 2008

1 commit

  • Dave Young reported warnings from lockdep that the workqueue API
    can sometimes try to register lockdep classes with the same key
    but different names. This is not permitted in lockdep.

    Unfortunately, I was unaware of that restriction when I wrote
    the code to debug workqueue problems with lockdep and used the
    workqueue name as the lockdep class name. This can obviously
    lead to the problem if the workqueue name is dynamic.

    This patch solves the problem by always using a constant name
    for the workqueue's lockdep class, namely either the constant
    name that was passed in or a string consisting of the variable
    name.

    Signed-off-by: Johannes Berg
    Signed-off-by: Ingo Molnar
    Signed-off-by: Peter Zijlstra

    Johannes Berg
     

20 Oct, 2007

1 commit

  • In the following scenario:

    code path 1:
    my_function() -> lock(L1); ...; flush_workqueue(); ...

    code path 2:
    run_workqueue() -> my_work() -> ...; lock(L1); ...

    you can get a deadlock when my_work() is queued or running
    but my_function() has acquired L1 already.

    This patch adds a pseudo-lock to each workqueue to make lockdep
    warn about this scenario.

    [akpm@linux-foundation.org: coding-style fixes]
    Signed-off-by: Johannes Berg
    Acked-by: Oleg Nesterov
    Acked-by: Ingo Molnar
    Acked-by: Peter Zijlstra
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Johannes Berg