From a9668c9f07d160e2c445d08fdb12facc261a27e8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 20 Jul 2010 18:40:29 +0000 Subject: [PATCH] Micro-optimized srpt_handle_rdma_comp(). Assigned names to the three threading modes. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1845 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- srpt/src/ib_srpt.c | 54 +++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index ea6c26bd7..d709a7cd7 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -70,9 +70,15 @@ MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol target " MODULE_LICENSE("Dual BSD/GPL"); /* - * Local data structures. + * Local data types. */ +enum threading_mode { + MODE_SIRQ = 0, + MODE_SINGLE_THREADED = 1, + MODE_MULTITHREADED = 2, +}; + struct srpt_thread { /* Protects thread_ioctx_list. */ spinlock_t thread_lock; @@ -1102,7 +1108,6 @@ static void srpt_reset_ioctx(struct srpt_rdma_ch *ch, struct srpt_ioctx *ioctx) if (srpt_post_recv(ch->sport->sdev, ioctx)) PRINT_ERROR("%s", "SRQ post_recv failed - this is serious."); - /* we should queue it back to free_ioctx queue */ else { int req_lim; @@ -1210,11 +1215,7 @@ static void srpt_handle_err_comp(struct srpt_rdma_ch *ch, struct ib_wc *wc, enum srpt_command_state state; struct scst_cmd *scmnd; - if (wc->wr_id & SRPT_OP_RECV) - PRINT_INFO("%s", "Received receive completion error. Is the" - " ib_srpt.ko kernel module being unloaded ? Has an" - " InfiniBand cable been disconnected ?"); - else { + if (!(wc->wr_id & SRPT_OP_RECV)) { ioctx = sdev->ioctx_ring[wc->wr_id]; state = srpt_get_cmd_state(ioctx); scmnd = ioctx->scmnd; @@ -1257,7 +1258,7 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch, EXTRACHECKS_WARN_ON((state == SRPT_STATE_MGMT_RSP_SENT) != (scmnd == NULL)); - if (state == SRPT_STATE_DONE) + if (unlikely(state == SRPT_STATE_DONE)) PRINT_ERROR("IB completion has been received too late for" " wr_id = %u.", ioctx->index); else if (scmnd) { @@ -1279,18 +1280,15 @@ static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch, scmnd = ioctx->scmnd; WARN_ON(!scmnd); - if (!scmnd) + if (unlikely(!scmnd)) return; state = srpt_test_and_set_cmd_state(ioctx, SRPT_STATE_NEED_DATA, SRPT_STATE_DATA_IN); - WARN_ON(state != SRPT_STATE_NEED_DATA); + EXTRACHECKS_WARN_ON(state != SRPT_STATE_NEED_DATA); - if (unlikely(scst_cmd_aborted(scmnd))) - srpt_abort_scst_cmd(ioctx, context); - else - scst_rx_data(ioctx->scmnd, SCST_RX_STATUS_SUCCESS, context); + scst_rx_data(ioctx->scmnd, SCST_RX_STATUS_SUCCESS, context); } /** @@ -1683,27 +1681,30 @@ err: } /** - * srpt_test_ioctx_list() - Tests whether there is more work for the kernel thr. + * srpt_test_ioctx_list() - Returns false if the kernel thread should sleep. * - * @pre thread == 1 + * @pre thread == MODE_SINGLE_THREADED * @pre the caller holds a lock on srpt_thread.thread_lock */ static inline int srpt_test_ioctx_list(void) { - int res = (!list_empty(&srpt_thread.thread_ioctx_list) || - unlikely(kthread_should_stop())); - return res; + EXTRACHECKS_WARN_ON(thread != MODE_SINGLE_THREADED); + + return !list_empty(&srpt_thread.thread_ioctx_list) + || unlikely(kthread_should_stop()); } /** * srpt_schedule_thread() - Add 'ioctx' to the tail of the ioctx list. * - * @pre thread == 1 + * @pre thread == MODE_SINGLE_THREADED */ static inline void srpt_schedule_thread(struct srpt_ioctx *ioctx) { unsigned long flags; + EXTRACHECKS_WARN_ON(thread != MODE_SINGLE_THREADED); + spin_lock_irqsave(&srpt_thread.thread_lock, flags); list_add_tail(&ioctx->comp_list, &srpt_thread.thread_ioctx_list); spin_unlock_irqrestore(&srpt_thread.thread_lock, flags); @@ -1764,7 +1765,7 @@ static void srpt_rcv_completion(struct ib_cq *cq, void *ctx) if (unlikely(req_lim < 0)) PRINT_ERROR("req_lim = %d < 0", req_lim); ioctx = sdev->ioctx_ring[wc.wr_id & ~SRPT_OP_RECV]; - if (thread == 1) { + if (thread == MODE_SINGLE_THREADED) { ioctx->ch = ch; ioctx->op = wc.opcode; srpt_schedule_thread(ioctx); @@ -1804,7 +1805,7 @@ static void srpt_send_completion(struct ib_cq *cq, void *ctx) ioctx = sdev->ioctx_ring[wc.wr_id]; atomic_add(wc.opcode == IB_WC_SEND ? 1 : ioctx->n_rdma, &ch->sq_wr_avail); - if (thread == 1) { + if (thread == MODE_SINGLE_THREADED) { ioctx->ch = ch; ioctx->op = wc.opcode; srpt_schedule_thread(ioctx); @@ -1833,12 +1834,14 @@ static void srpt_send_completion(struct ib_cq *cq, void *ctx) * This kernel thread is only created when the module parameter 'thread' equals * one. This thread processes the ioctx list srpt_thread.thread_ioctx_list. * - * @pre thread == 1 + * @pre thread == MODE_SINGLE_THREADED */ static int srpt_ioctx_thread(void *arg) { struct srpt_ioctx *ioctx; + EXTRACHECKS_WARN_ON(thread != MODE_SINGLE_THREADED); + /* Hibernation / freezing of the SRPT kernel thread is not supported. */ current->flags |= PF_NOFREEZE; @@ -3728,16 +3731,17 @@ static int __init srpt_init_module(void) } switch (thread) { - case 0: + case MODE_SIRQ: /* IRQ context */ srpt_context = SCST_CONTEXT_TASKLET; srpt_template.rdy_to_xfer_atomic = true; break; - case 1: + case MODE_SINGLE_THREADED: /* single kernel thread (created by ib_srpt) */ srpt_context = SCST_CONTEXT_DIRECT; srpt_template.rdy_to_xfer_atomic = false; break; + case MODE_MULTITHREADED: default: /* multiple kernel threads (created by the SCST core) */ srpt_context = SCST_CONTEXT_THREAD;