lkml.org 
[lkml]   [2009]   [Apr]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 08/13] GRU - fix handling of mesq failures
    From: Jack Steiner <steiner@sgi.com>

    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: Jack Steiner <steiner@sgi.com>

    ---
    drivers/misc/sgi-gru/grukservices.c | 33 ++++++++++++++++++++++++---------
    1 file changed, 24 insertions(+), 9 deletions(-)

    Index: linux/drivers/misc/sgi-gru/grukservices.c
    ===================================================================
    --- linux.orig/drivers/misc/sgi-gru/grukservices.c 2009-03-07 16:00:29.000000000 -0600
    +++ linux/drivers/misc/sgi-gru/grukservices.c 2009-03-11 10:16:34.000000000 -0500
    @@ -503,6 +503,29 @@ static void send_message_queue_interrupt
    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
    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
    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();


    \
     
     \ /
      Last update: 2009-04-06 18:15    [W:4.525 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site