Commit db37c505 authored by Mike Christie's avatar Mike Christie Committed by James Bottomley

[SCSI] iscsi_tcp: fix xmittask oops

XMSTATE_SOL_HDR could be set when the xmit thread tests it, but there may
not be anything on the r2tqueue yet. Move the XMSTATE_SOL_HDR set
before the addition to the queue to make sure that when we pull something
off it it is valid. This does not add locks around the xmstate test or make
that a atmoic_t because this is a fast path and if it is set when we test it
we can handle it there without the overhead. Later on we check the xmitqueue
for all requests with the session lock so we will not miss it.
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent d6e24d1c
...@@ -415,8 +415,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) ...@@ -415,8 +415,8 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
iscsi_solicit_data_init(conn, ctask, r2t); iscsi_solicit_data_init(conn, ctask, r2t);
tcp_ctask->exp_r2tsn = r2tsn + 1; tcp_ctask->exp_r2tsn = r2tsn + 1;
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
__kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
list_move_tail(&ctask->running, &conn->xmitqueue); list_move_tail(&ctask->running, &conn->xmitqueue);
scsi_queue_work(session->host, &conn->xmitwork); scsi_queue_work(session->host, &conn->xmitwork);
...@@ -1627,9 +1627,12 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn, ...@@ -1627,9 +1627,12 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
tcp_ctask->xmstate |= XMSTATE_SOL_DATA; tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
if (!tcp_ctask->r2t) if (!tcp_ctask->r2t) {
spin_lock_bh(&session->lock);
__kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
sizeof(void*)); sizeof(void*));
spin_unlock_bh(&session->lock);
}
send_hdr: send_hdr:
r2t = tcp_ctask->r2t; r2t = tcp_ctask->r2t;
dtask = &r2t->dtask; dtask = &r2t->dtask;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment