lkml.org 
[lkml]   [2014]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[v2.6.34-stable 095/213] Fix a dead loop in async_synchronize_full()
    Date
    From: Li Zhong <zhong@linux.vnet.ibm.com>

    -------------------
    This is a commit scheduled for the next v2.6.34 longterm release.
    http://git.kernel.org/?p=linux/kernel/git/paulg/longterm-queue-2.6.34.git
    If you see a problem with using this for longterm, please comment.
    -------------------

    [commit 45516ddc16abc923104d78bb3eb772ac0a09e33e in v3.0.44 - paulg ]

    [Fixed upstream by commits 2955b47d2c1983998a8c5915cb96884e67f7cb53 and
    a4683487f90bfe3049686fc5c566bdc1ad03ace6 from Dan Williams, but they are much
    more intrusive than this tiny fix, according to Andrew - gregkh]

    This patch tries to fix a dead loop in async_synchronize_full(), which
    could be seen when preemption is disabled on a single cpu machine.

    void async_synchronize_full(void)
    {
    do {
    async_synchronize_cookie(next_cookie);
    } while (!list_empty(&async_running) || !
    list_empty(&async_pending));
    }

    async_synchronize_cookie() calls async_synchronize_cookie_domain() with
    &async_running as the default domain to synchronize.

    However, there might be some works in the async_pending list from other
    domains. On a single cpu system, without preemption, there is no chance
    for the other works to finish, so async_synchronize_full() enters a dead
    loop.

    It seems async_synchronize_full() wants to synchronize all entries in
    all running lists(domains), so maybe we could just check the entry_count
    to know whether all works are finished.

    Currently, async_synchronize_cookie_domain() expects a non-NULL running
    list ( if NULL, there would be NULL pointer dereference ), so maybe a
    NULL pointer could be used as an indication for the functions to
    synchronize all works in all domains.

    Reported-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
    Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
    Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
    Tested-by: Christian Kujau <lists@nerdbynature.de>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: Dan Williams <dan.j.williams@gmail.com>
    Cc: Christian Kujau <lists@nerdbynature.de>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: Cong Wang <xiyou.wangcong@gmail.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
    ---
    kernel/async.c | 13 +++++++++----
    1 file changed, 9 insertions(+), 4 deletions(-)

    diff --git a/kernel/async.c b/kernel/async.c
    index 15319d6c18fe..b640ffc3f5a1 100644
    --- a/kernel/async.c
    +++ b/kernel/async.c
    @@ -94,6 +94,13 @@ static async_cookie_t __lowest_in_progress(struct list_head *running)
    {
    struct async_entry *entry;

    + if (!running) { /* just check the entry count */
    + if (atomic_read(&entry_count))
    + return 0; /* smaller than any cookie */
    + else
    + return next_cookie;
    + }
    +
    if (!list_empty(running)) {
    entry = list_first_entry(running,
    struct async_entry, list);
    @@ -249,9 +256,7 @@ EXPORT_SYMBOL_GPL(async_schedule_domain);
    */
    void async_synchronize_full(void)
    {
    - do {
    - async_synchronize_cookie(next_cookie);
    - } while (!list_empty(&async_running) || !list_empty(&async_pending));
    + async_synchronize_cookie_domain(next_cookie, NULL);
    }
    EXPORT_SYMBOL_GPL(async_synchronize_full);

    @@ -271,7 +276,7 @@ EXPORT_SYMBOL_GPL(async_synchronize_full_domain);
    /**
    * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing
    * @cookie: async_cookie_t to use as checkpoint
    - * @running: running list to synchronize on
    + * @running: running list to synchronize on, NULL indicates all lists
    *
    * This function waits until all asynchronous function calls for the
    * synchronization domain specified by the running list @list submitted
    --
    1.8.5.2


    \
     
     \ /
      Last update: 2014-02-05 22:41    [W:4.754 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site