ib_srpt: Make sure that pre-RTU requests are processed before post-RTU requests

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4200 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2012-04-10 14:58:31 +00:00
parent 83dbc69d4e
commit b675a6b02c
2 changed files with 42 additions and 19 deletions

View File

@@ -1810,7 +1810,6 @@ static void srpt_handle_new_iu(struct srpt_rdma_ch *ch,
enum scst_exec_context context)
{
struct srp_cmd *srp_cmd;
enum rdma_ch_state ch_state;
BUG_ON(!ch);
BUG_ON(!recv_ioctx);
@@ -1819,9 +1818,8 @@ static void srpt_handle_new_iu(struct srpt_rdma_ch *ch,
recv_ioctx->ioctx.dma, srp_max_req_size,
DMA_FROM_DEVICE);
ch_state = ch->state;
srp_cmd = recv_ioctx->ioctx.buf;
if (unlikely(ch_state == CH_CONNECTING)) {
if (unlikely(!ch->rtu_received)) {
list_add_tail(&recv_ioctx->wait_list, &ch->cmd_wait_list);
goto out;
}
@@ -1890,6 +1888,22 @@ static void srpt_process_rcv_completion(struct ib_cq *cq,
}
}
static void srpt_process_wait_list(struct srpt_rdma_ch *ch,
enum scst_exec_context context)
{
struct srpt_recv_ioctx *recv_ioctx, *tmp;
struct srpt_send_ioctx *send_ioctx;
list_for_each_entry_safe(recv_ioctx, tmp, &ch->cmd_wait_list,
wait_list) {
send_ioctx = srpt_get_send_ioctx(ch);
if (!send_ioctx)
break;
list_del(&recv_ioctx->wait_list);
srpt_handle_new_iu(ch, recv_ioctx, send_ioctx, context);
}
}
/**
* srpt_process_send_completion() - Process an IB send completion.
*
@@ -1938,18 +1952,10 @@ static void srpt_process_send_completion(struct ib_cq *cq,
}
}
while (unlikely(opcode == SRPT_SEND
&& !list_empty(&ch->cmd_wait_list)
&& ch->state == CH_LIVE
&& (send_ioctx = srpt_get_send_ioctx(ch)) != NULL)) {
struct srpt_recv_ioctx *recv_ioctx;
recv_ioctx = list_first_entry(&ch->cmd_wait_list,
struct srpt_recv_ioctx,
wait_list);
list_del(&recv_ioctx->wait_list);
srpt_handle_new_iu(ch, recv_ioctx, send_ioctx, context);
}
if (unlikely(opcode == SRPT_SEND &&
ch->rtu_received &&
!list_empty(&ch->cmd_wait_list)))
srpt_process_wait_list(ch, context);
}
static void srpt_process_completion(struct ib_cq *cq,
@@ -1997,11 +2003,25 @@ static int srpt_compl_thread(void *arg)
ch = arg;
BUG_ON(!ch);
while (!ch->last_wqe_received) {
set_current_state(TASK_INTERRUPTIBLE);
set_current_state(TASK_INTERRUPTIBLE);
while (ch->state < CH_LIVE) {
srpt_process_completion(ch->cq, ch, SCST_CONTEXT_THREAD,
SCST_CONTEXT_DIRECT);
schedule();
set_current_state(TASK_INTERRUPTIBLE);
}
set_current_state(TASK_RUNNING);
srpt_process_wait_list(ch, SCST_CONTEXT_THREAD);
ch->rtu_received = true;
set_current_state(TASK_INTERRUPTIBLE);
while (!ch->last_wqe_received) {
srpt_process_completion(ch->cq, ch, SCST_CONTEXT_THREAD,
SCST_CONTEXT_DIRECT);
schedule();
set_current_state(TASK_INTERRUPTIBLE);
}
set_current_state(TASK_RUNNING);

View File

@@ -302,9 +302,11 @@ enum rdma_ch_state {
* credit algorithm in the SRP spec.
* @spinlock: Protects free_list.
* @free_list: Head of list with free send I/O contexts.
* @ioctx_ring:
* @wc:
* @ioctx_ring: Send I/O context ring.
* @wc: Work completion array.
* @state: channel state. See also enum rdma_ch_state.
* @rtu_received: Whether IB CM RTU event has been received and the requests
* received before that event have been processed.
* @list: node for insertion in the srpt_device.rch_list list.
* @cmd_wait_list: list of SCST commands that arrived before the RTU event. This
* list contains struct srpt_ioctx elements and is protected
@@ -335,6 +337,7 @@ struct srpt_rdma_ch {
wait_queue_head_t state_wq;
struct list_head list;
struct list_head cmd_wait_list;
bool rtu_received;
bool last_wqe_received;
struct scst_session *scst_sess;