lkml.org 
[lkml]   [2017]   [Dec]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.9 099/156] powerpc/opal: Fix EBUSY bug in acquiring tokens
    Date
    From: "William A. Kennington III" <wak@google.com>

    [ Upstream commit 71e24d7731a2903b1ae2bba2b2971c654d9c2aa6 ]

    The current code checks the completion map to look for the first token
    that is complete. In some cases, a completion can come in but the
    token can still be on lease to the caller processing the completion.
    If this completed but unreleased token is the first token found in the
    bitmap by another tasks trying to acquire a token, then the
    __test_and_set_bit call will fail since the token will still be on
    lease. The acquisition will then fail with an EBUSY.

    This patch reorganizes the acquisition code to look at the
    opal_async_token_map for an unleased token. If the token has no lease
    it must have no outstanding completions so we should never see an
    EBUSY, unless we have leased out too many tokens. Since
    opal_async_get_token_inrerruptible is protected by a semaphore, we
    will practically never see EBUSY anymore.

    Fixes: 8d7248232208 ("powerpc/powernv: Infrastructure to support OPAL async completion")
    Signed-off-by: William A. Kennington III <wak@google.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
    ---
    arch/powerpc/platforms/powernv/opal-async.c | 6 +++---
    1 file changed, 3 insertions(+), 3 deletions(-)

    diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c
    index 83bebeec0fea..0f7b16e29347 100644
    --- a/arch/powerpc/platforms/powernv/opal-async.c
    +++ b/arch/powerpc/platforms/powernv/opal-async.c
    @@ -39,18 +39,18 @@ int __opal_async_get_token(void)
    int token;

    spin_lock_irqsave(&opal_async_comp_lock, flags);
    - token = find_first_bit(opal_async_complete_map, opal_max_async_tokens);
    + token = find_first_zero_bit(opal_async_token_map, opal_max_async_tokens);
    if (token >= opal_max_async_tokens) {
    token = -EBUSY;
    goto out;
    }

    - if (__test_and_set_bit(token, opal_async_token_map)) {
    + if (!__test_and_clear_bit(token, opal_async_complete_map)) {
    token = -EBUSY;
    goto out;
    }

    - __clear_bit(token, opal_async_complete_map);
    + __set_bit(token, opal_async_token_map);

    out:
    spin_unlock_irqrestore(&opal_async_comp_lock, flags);
    --
    2.11.0
    \
     
     \ /
      Last update: 2017-12-07 18:13    [W:4.069 / U:0.356 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site