On Mon, 2017-11-06 at 20:41 +1100, Michael Ellerman wrote: > 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; > } > >
Thanks!! > > > > +/* > > + * 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