Skip to content
Snippets Groups Projects
Commit 17b49a67 authored by Jack Steiner's avatar Jack Steiner Committed by Linus Torvalds
Browse files

gru: fix handling of mesq failures


Fix endcase in handling GRU message queue failures due to NACKs of PUT
requests.  Must ensure that the "present" bits are cleared before
resending the message.

Signed-off-by: default avatarJack Steiner <steiner@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3eac2e95
No related branches found
No related tags found
No related merge requests found
......@@ -503,6 +503,29 @@ static void send_message_queue_interrupt(struct gru_message_queue_desc *mqd)
mqd->interrupt_vector);
}
/*
* Handle a PUT failure. Note: if message was a 2-line message, one of the
* lines might have successfully have been written. Before sending the
* message, "present" must be cleared in BOTH lines to prevent the receiver
* from prematurely seeing the full message.
*/
static int send_message_put_nacked(void *cb, struct gru_message_queue_desc *mqd,
void *mesg, int lines)
{
unsigned long m;
m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
if (lines == 2) {
gru_vset(cb, m, 0, XTYPE_CL, lines, 1, IMA);
if (gru_wait(cb) != CBS_IDLE)
return MQE_UNEXPECTED_CB_ERR;
}
gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
if (gru_wait(cb) != CBS_IDLE)
return MQE_UNEXPECTED_CB_ERR;
send_message_queue_interrupt(mqd);
return MQE_OK;
}
/*
* Handle a gru_mesq failure. Some of these failures are software recoverable
......@@ -512,7 +535,6 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
void *mesg, int lines)
{
int substatus, ret = 0;
unsigned long m;
substatus = gru_get_cb_message_queue_substatus(cb);
switch (substatus) {
......@@ -534,14 +556,7 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
break;
case CBSS_PUT_NACKED:
STAT(mesq_send_put_nacked);
m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
if (gru_wait(cb) == CBS_IDLE) {
ret = MQE_OK;
send_message_queue_interrupt(mqd);
} else {
ret = MQE_UNEXPECTED_CB_ERR;
}
ret = send_message_put_nacked(cb, mqd, mesg, lines);
break;
default:
BUG();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment