[PATCH] powerpc/opal: Fix EBUSY bug in acquiring tokens

William A. Kennington III wak at google.com
Sat Sep 23 09:58:00 AEST 2017


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.

Signed-off-by: William A. Kennington III <wak at google.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 cf33769a7b72..45b3feb8aa2f 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.14.1.821.g8fa685d3b7-goog



More information about the Linuxppc-dev mailing list