lkml.org 
[lkml]   [2007]   [Feb]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 24/59] IB/iser: return error code when PDUs may not be sent
    -stable review patch.  If anyone has any objections, please let us know.
    ------------------

    From: Erez Zilber <erezz@voltaire.com>

    iSER limits the number of outstanding PDUs to send. When this threshold is
    reached, it should return an error code (-ENOBUFS) instead of setting the
    suspend_tx bit (which should be used only by libiscsi). Without this fix,
    during logout, open-iscsi over iSER tries to logout forever.

    Signed-off-by: Erez Zilber <erezz@voltaire.com>
    Signed-off-by: Chris Wright <chrisw@sous-sol.org>
    ---
    drivers/infiniband/ulp/iser/iscsi_iser.c | 4 ++--
    drivers/infiniband/ulp/iser/iser_initiator.c | 26 ++++++++++++--------------
    2 files changed, 14 insertions(+), 16 deletions(-)

    --- linux-2.6.19.2.orig/drivers/infiniband/ulp/iser/iscsi_iser.c
    +++ linux-2.6.19.2/drivers/infiniband/ulp/iser/iscsi_iser.c
    @@ -177,7 +177,7 @@ iscsi_iser_mtask_xmit(struct iscsi_conn
    * - if yes, the mtask is recycled at iscsi_complete_pdu
    * - if no, the mtask is recycled at iser_snd_completion
    */
    - if (error && error != -EAGAIN)
    + if (error && error != -ENOBUFS)
    iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);

    return error;
    @@ -241,7 +241,7 @@ iscsi_iser_ctask_xmit(struct iscsi_conn
    error = iscsi_iser_ctask_xmit_unsol_data(conn, ctask);

    iscsi_iser_ctask_xmit_exit:
    - if (error && error != -EAGAIN)
    + if (error && error != -ENOBUFS)
    iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
    return error;
    }
    --- linux-2.6.19.2.orig/drivers/infiniband/ulp/iser/iser_initiator.c
    +++ linux-2.6.19.2/drivers/infiniband/ulp/iser/iser_initiator.c
    @@ -304,18 +304,14 @@ int iser_conn_set_full_featured_mode(str
    static int
    iser_check_xmit(struct iscsi_conn *conn, void *task)
    {
    - int rc = 0;
    struct iscsi_iser_conn *iser_conn = conn->dd_data;

    - write_lock_bh(conn->recv_lock);
    if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
    ISER_QP_MAX_REQ_DTOS) {
    - iser_dbg("%ld can't xmit task %p, suspending tx\n",jiffies,task);
    - set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
    - rc = -EAGAIN;
    + iser_dbg("%ld can't xmit task %p\n",jiffies,task);
    + return -ENOBUFS;
    }
    - write_unlock_bh(conn->recv_lock);
    - return rc;
    + return 0;
    }


    @@ -340,7 +336,7 @@ int iser_send_command(struct iscsi_conn
    return -EPERM;
    }
    if (iser_check_xmit(conn, ctask))
    - return -EAGAIN;
    + return -ENOBUFS;

    edtl = ntohl(hdr->data_length);

    @@ -426,7 +422,7 @@ int iser_send_data_out(struct iscsi_conn
    }

    if (iser_check_xmit(conn, ctask))
    - return -EAGAIN;
    + return -ENOBUFS;

    itt = ntohl(hdr->itt);
    data_seg_len = ntoh24(hdr->dlength);
    @@ -500,7 +496,7 @@ int iser_send_control(struct iscsi_conn
    }

    if (iser_check_xmit(conn,mtask))
    - return -EAGAIN;
    + return -ENOBUFS;

    /* build the tx desc regd header and add it to the tx desc dto */
    mdesc->type = ISCSI_TX_CONTROL;
    @@ -609,6 +605,7 @@ void iser_snd_completion(struct iser_des
    struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
    struct iscsi_conn *conn = iser_conn->iscsi_conn;
    struct iscsi_mgmt_task *mtask;
    + int resume_tx = 0;

    iser_dbg("Initiator, Data sent dto=0x%p\n", dto);

    @@ -617,15 +614,16 @@ void iser_snd_completion(struct iser_des
    if (tx_desc->type == ISCSI_TX_DATAOUT)
    kmem_cache_free(ig.desc_cache, tx_desc);

    + if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
    + ISER_QP_MAX_REQ_DTOS)
    + resume_tx = 1;
    +
    atomic_dec(&ib_conn->post_send_buf_count);

    - write_lock(conn->recv_lock);
    - if (conn->suspend_tx) {
    + if (resume_tx) {
    iser_dbg("%ld resuming tx\n",jiffies);
    - clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
    scsi_queue_work(conn->session->host, &conn->xmitwork);
    }
    - write_unlock(conn->recv_lock);

    if (tx_desc->type == ISCSI_TX_CONTROL) {
    /* this arithmetic is legal by libiscsi dd_data allocation */
    --
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-02-03 03:55    [W:0.025 / U:31.028 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site