Cyril Bur <cyril...@gmail.com> writes:

> diff --git a/arch/powerpc/platforms/powernv/opal-async.c 
> b/arch/powerpc/platforms/powernv/opal-async.c
> index c43421ab2d2f..fbae8a37ce2c 100644
> --- a/arch/powerpc/platforms/powernv/opal-async.c
> +++ b/arch/powerpc/platforms/powernv/opal-async.c
> @@ -23,40 +23,45 @@
>  #include <asm/machdep.h>
>  #include <asm/opal.h>
>  
> -#define N_ASYNC_COMPLETIONS  64
> +enum opal_async_token_state {
> +     ASYNC_TOKEN_UNALLOCATED = 0,
> +     ASYNC_TOKEN_ALLOCATED,
> +     ASYNC_TOKEN_COMPLETED
> +};
> +
> +struct opal_async_token {
> +     enum opal_async_token_state state;
> +     struct opal_msg response;
> +};
>  
> -static DECLARE_BITMAP(opal_async_complete_map, N_ASYNC_COMPLETIONS) = {~0UL};
> -static DECLARE_BITMAP(opal_async_token_map, N_ASYNC_COMPLETIONS);
>  static DECLARE_WAIT_QUEUE_HEAD(opal_async_wait);
>  static DEFINE_SPINLOCK(opal_async_comp_lock);
>  static struct semaphore opal_async_sem;
> -static struct opal_msg *opal_async_responses;
>  static unsigned int opal_max_async_tokens;
> +static struct opal_async_token *opal_async_tokens;
>  
>  static int __opal_async_get_token(void)
>  {
>       unsigned long flags;
> -     int token;
> +     int token = -EBUSY;
>  
>       spin_lock_irqsave(&opal_async_comp_lock, flags);
> -     token = find_first_bit(opal_async_complete_map, opal_max_async_tokens);
> -     if (token >= opal_max_async_tokens) {
> -             token = -EBUSY;
> -             goto out;
> +     for (token = 0; token < opal_max_async_tokens; token++) {
> +             if (opal_async_tokens[token].state == ASYNC_TOKEN_UNALLOCATED) {
> +                     opal_async_tokens[token].state = ASYNC_TOKEN_ALLOCATED;
> +                     goto out;
> +             }
>       }
> -
> -     if (__test_and_set_bit(token, opal_async_token_map)) {
> -             token = -EBUSY;
> -             goto out;
> -     }
> -
> -     __clear_bit(token, opal_async_complete_map);
> -
>  out:
>       spin_unlock_irqrestore(&opal_async_comp_lock, flags);
>       return token;
>  }

Resulting in:

 static int __opal_async_get_token(void)
 {
        unsigned long flags;
+       int token = -EBUSY;
 
        spin_lock_irqsave(&opal_async_comp_lock, flags);
+       for (token = 0; token < opal_max_async_tokens; token++) {
+               if (opal_async_tokens[token].state == ASYNC_TOKEN_UNALLOCATED) {
+                       opal_async_tokens[token].state = ASYNC_TOKEN_ALLOCATED;
+                       goto out;
+               }
        }
 out:
        spin_unlock_irqrestore(&opal_async_comp_lock, flags);
        return token;
 }

So when no unallocated token is found we return opal_max_async_tokens :(

I changed it to:

static int __opal_async_get_token(void)
{
        unsigned long flags;
        int i, token = -EBUSY;

        spin_lock_irqsave(&opal_async_comp_lock, flags);

        for (i = 0; i < opal_max_async_tokens; i++) {
                if (opal_async_tokens[i].state == ASYNC_TOKEN_UNALLOCATED) {
                        opal_async_tokens[i].state = ASYNC_TOKEN_ALLOCATED;
                        token = i;
                        break;
                }
        }

        spin_unlock_irqrestore(&opal_async_comp_lock, flags);
        return token;
}


>  
> +/*
> + * Note: If the returned token is used in an opal call and opal returns
> + * OPAL_ASYNC_COMPLETION you MUST opal_async_wait_response() before
                                     ^
                                     call


cheers

Reply via email to