powerpc/powernv: Fix issues in opal_async
* Properly return the full opal_msg from an async completion. * Don't keep bugging OPAL, wait 100us or so. With some minor changes to DELAY() to drop to very low priority, the thread won't hog the CPU while polling for the async completion.
This commit is contained in:
parent
734b726d80
commit
947079ebee
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=345974
@ -201,7 +201,7 @@ struct opal_ipmi_msg {
|
|||||||
int opal_init_async_tokens(int);
|
int opal_init_async_tokens(int);
|
||||||
int opal_alloc_async_token(void);
|
int opal_alloc_async_token(void);
|
||||||
void opal_free_async_token(int);
|
void opal_free_async_token(int);
|
||||||
int opal_wait_completion(void *, uint64_t, uint64_t);
|
int opal_wait_completion(void *, uint64_t, int);
|
||||||
|
|
||||||
typedef void (*opal_msg_handler_fn)(void *, struct opal_msg *);
|
typedef void (*opal_msg_handler_fn)(void *, struct opal_msg *);
|
||||||
EVENTHANDLER_DECLARE(OPAL_ASYNC_COMP, opal_msg_handler_fn);
|
EVENTHANDLER_DECLARE(OPAL_ASYNC_COMP, opal_msg_handler_fn);
|
||||||
|
@ -50,8 +50,8 @@ static vmem_t *async_token_pool;
|
|||||||
static void opal_handle_async_completion(void *, struct opal_msg *);
|
static void opal_handle_async_completion(void *, struct opal_msg *);
|
||||||
|
|
||||||
struct async_completion {
|
struct async_completion {
|
||||||
uint64_t rval;
|
volatile uint64_t completed;
|
||||||
bool completed;
|
struct opal_msg msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct async_completion *completions;
|
struct async_completion *completions;
|
||||||
@ -98,16 +98,21 @@ opal_free_async_token(int token)
|
|||||||
* of the operation, error if it returns early.
|
* of the operation, error if it returns early.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
opal_wait_completion(void *buf, uint64_t size, uint64_t token)
|
opal_wait_completion(void *buf, uint64_t size, int token)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
err = opal_call(OPAL_CHECK_ASYNC_COMPLETION,
|
err = opal_call(OPAL_CHECK_ASYNC_COMPLETION,
|
||||||
vtophys(buf), size, token);
|
vtophys(buf), size, token);
|
||||||
if (err == OPAL_BUSY)
|
if (err == OPAL_BUSY) {
|
||||||
if (completions[token].completed)
|
if (completions[token].completed) {
|
||||||
return (completions[token].rval);
|
atomic_thread_fence_acq();
|
||||||
|
memcpy(buf, &completions[token].msg, size);
|
||||||
|
return (OPAL_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DELAY(100);
|
||||||
} while (err == OPAL_BUSY);
|
} while (err == OPAL_BUSY);
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
@ -118,7 +123,7 @@ static void opal_handle_async_completion(void *arg, struct opal_msg *msg)
|
|||||||
int token;
|
int token;
|
||||||
|
|
||||||
token = msg->params[0];
|
token = msg->params[0];
|
||||||
completions[token].rval = msg->params[1];
|
memcpy(&completions[token].msg, msg, sizeof(*msg));
|
||||||
isync();
|
atomic_thread_fence_rel();
|
||||||
completions[token].completed = true;
|
completions[token].completed = true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user