diff --git a/qla_isp/linux/isp_scst.c b/qla_isp/linux/isp_scst.c index 1355f6c5b..2fbac619b 100644 --- a/qla_isp/linux/isp_scst.c +++ b/qla_isp/linux/isp_scst.c @@ -480,9 +480,10 @@ rx_loop: } scst_cmd_set_expected(scst_cmd, dir, len); } - scst_cmd_init_done(scst_cmd, SCST_CONTEXT_TASKLET); spin_unlock_irq(&bc->tmds_lock); + scst_cmd_init_done(scst_cmd, SCST_CONTEXT_DIRECT_ATOMIC); + goto rx_loop; } @@ -620,6 +621,7 @@ scsi_target_done_cmd(tmd_cmd_t *tmd) bus_t *bp; struct scst_cmd *scst_cmd; tmd_xact_t *xact = &tmd->cd_xact; + enum scst_exec_context context = scst_estimate_context(); SDprintk2("scsi_target: TMD_DONE[%llx] %p hf %x lf %x xfrlen %d totlen %d moved %d\n", tmd->cd_tagval, tmd, xact->td_hflags, xact->td_lflags, xact->td_xfrlen, tmd->cd_totlen, tmd->cd_moved); @@ -642,7 +644,7 @@ scsi_target_done_cmd(tmd_cmd_t *tmd) if (unlikely(xact->td_error)) { scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_FAILED); } - scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_TASKLET); + scst_tgt_cmd_done(scst_cmd, context); return; } @@ -653,12 +655,12 @@ scsi_target_done_cmd(tmd_cmd_t *tmd) if (unlikely(xact->td_error)) { rx_status = SCST_RX_STATUS_ERROR; } - scst_rx_data(scst_cmd, rx_status, SCST_CONTEXT_TASKLET); + scst_rx_data(scst_cmd, rx_status, context); } else { if (unlikely(xact->td_error)) { scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_FAILED); } - scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_TASKLET); + scst_tgt_cmd_done(scst_cmd, context); } } else { ; /* we don't have all data, do nothing */ @@ -669,7 +671,7 @@ scsi_target_done_cmd(tmd_cmd_t *tmd) if (unlikely(xact->td_error)) { scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_FAILED); } - scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_TASKLET); + scst_tgt_cmd_done(scst_cmd, context); } else { Eprintk("don't know what to do with TMD_DONE[%llx] cdb0 %x hf %x lf %x xfrlen %d totlen %d moved %d\n", tmd->cd_tagval, tmd->cd_cdb[0], xact->td_hflags, xact->td_lflags, xact->td_xfrlen, tmd->cd_totlen, tmd->cd_moved); diff --git a/scst/include/scst.h b/scst/include/scst.h index fd4d5ab5b..a68280015 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -2034,6 +2034,16 @@ static inline int scst_cmd_atomic(struct scst_cmd *cmd) return res; } +static inline enum scst_exec_context scst_estimate_context(void) +{ + if (in_irq()) + return SCST_CONTEXT_TASKLET; + else if (irqs_disabled()) + return SCST_CONTEXT_THREAD; + else + return SCST_CONTEXT_DIRECT_ATOMIC; +} + /* Returns cmd's session */ static inline struct scst_session *scst_cmd_get_session(struct scst_cmd *cmd) { diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 9afbbbf9c..42a922ff7 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -207,12 +207,13 @@ void scst_cmd_init_done(struct scst_cmd *cmd, cmd->cdb, cmd->cdb_len); #ifdef CONFIG_SCST_EXTRACHECKS - if (unlikely(in_irq()) && ((pref_context == SCST_CONTEXT_DIRECT) || - (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) { + if (unlikely((in_irq() || irqs_disabled())) && + ((pref_context == SCST_CONTEXT_DIRECT) || + (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) { PRINT_ERROR("Wrong context %d in IRQ from target %s, use " - "SCST_CONTEXT_TASKLET instead\n", pref_context, + "SCST_CONTEXT_THREAD instead\n", pref_context, cmd->tgtt->name); - pref_context = SCST_CONTEXT_TASKLET; + pref_context = SCST_CONTEXT_THREAD; } #endif @@ -791,12 +792,13 @@ void scst_restart_cmd(struct scst_cmd *cmd, int status, status); #ifdef CONFIG_SCST_EXTRACHECKS - if (in_irq() && ((pref_context == SCST_CONTEXT_DIRECT) || - (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) { + if ((in_irq() || irqs_disabled()) && + ((pref_context == SCST_CONTEXT_DIRECT) || + (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) { PRINT_ERROR("Wrong context %d in IRQ from target %s, use " - "SCST_CONTEXT_TASKLET instead\n", pref_context, + "SCST_CONTEXT_THREAD instead\n", pref_context, cmd->tgtt->name); - pref_context = SCST_CONTEXT_TASKLET; + pref_context = SCST_CONTEXT_THREAD; } #endif @@ -1052,12 +1054,13 @@ void scst_rx_data(struct scst_cmd *cmd, int status, status); #ifdef CONFIG_SCST_EXTRACHECKS - if (in_irq() && ((pref_context == SCST_CONTEXT_DIRECT) || - (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) { + if ((in_irq() || irqs_disabled()) && + ((pref_context == SCST_CONTEXT_DIRECT) || + (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) { PRINT_ERROR("Wrong context %d in IRQ from target %s, use " - "SCST_CONTEXT_TASKLET instead\n", pref_context, + "SCST_CONTEXT_THREAD instead\n", pref_context, cmd->tgtt->name); - pref_context = SCST_CONTEXT_TASKLET; + pref_context = SCST_CONTEXT_THREAD; } #endif @@ -1257,15 +1260,9 @@ static void scst_cmd_done(struct scsi_cmnd *scsi_cmd) cmd->state = SCST_CMD_STATE_PRE_DEV_DONE; - if (in_irq()) - context = SCST_CONTEXT_TASKLET; - else if (irqs_disabled()) - context = SCST_CONTEXT_THREAD; - else - context = SCST_CONTEXT_DIRECT_ATOMIC; - scst_proccess_redirect_cmd(cmd, - scst_optimize_post_exec_context(cmd, context), 0); + scst_optimize_post_exec_context(cmd, scst_estimate_context()), + 0); out: TRACE_EXIT(); @@ -1275,7 +1272,6 @@ out: static void scst_cmd_done(void *data, char *sense, int result, int resid) { struct scst_cmd *cmd; - enum scst_exec_context context; TRACE_ENTRY(); @@ -1287,15 +1283,9 @@ static void scst_cmd_done(void *data, char *sense, int result, int resid) cmd->state = SCST_CMD_STATE_PRE_DEV_DONE; - if (in_irq()) - context = SCST_CONTEXT_TASKLET; - else if (irqs_disabled()) - context = SCST_CONTEXT_THREAD; - else - context = SCST_CONTEXT_DIRECT_ATOMIC; - scst_proccess_redirect_cmd(cmd, - scst_optimize_post_exec_context(cmd, context), 0); + scst_optimize_post_exec_context(cmd, scst_estimate_context()), + 0); out: TRACE_EXIT(); @@ -3274,7 +3264,7 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic) TRACE_ENTRY(); - EXTRACHECKS_BUG_ON(in_irq()); + EXTRACHECKS_BUG_ON(in_irq() || irqs_disabled()); cmd->atomic = atomic; @@ -3743,7 +3733,7 @@ static int scst_call_dev_task_mgmt_fn(struct scst_mgmt_cmd *mcmd, if (h->task_mgmt_fn) { TRACE_MGMT_DBG("Calling dev handler %s task_mgmt_fn(fn=%d)", h->name, mcmd->fn); - EXTRACHECKS_BUG_ON(in_irq()); + EXTRACHECKS_BUG_ON(in_irq() || irqs_disabled()); res = h->task_mgmt_fn(mcmd, tgt_dev); TRACE_MGMT_DBG("Dev handler %s task_mgmt_fn() returned %d", h->name, res); diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index d1fa168d3..a88f897f0 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -655,7 +655,7 @@ static void srpt_handle_err_comp(struct srpt_rdma_ch *ch, struct ib_wc *wc) if (dir == SCST_DATA_NONE) scst_tgt_cmd_done(scmnd, - SCST_CONTEXT_DIRECT_ATOMIC); + scst_estimate_context()); else { dma_unmap_sg(sdev->device->dma_device, scst_cmd_get_sg(scmnd), @@ -676,7 +676,7 @@ static void srpt_handle_err_comp(struct srpt_rdma_ch *ch, struct ib_wc *wc) else if (scmnd->state == SCST_CMD_STATE_XMIT_WAIT) scst_tgt_cmd_done(scmnd, - SCST_CONTEXT_DIRECT_ATOMIC); + scst_estimate_context()); } } else srpt_reset_ioctx(ch, ioctx); @@ -1044,7 +1044,7 @@ static void srpt_completion(struct ib_cq *cq, void *ctx) switch (wc.opcode) { case IB_WC_SEND: srpt_handle_send_comp(ch, ioctx, - SCST_CONTEXT_DIRECT_ATOMIC); + scst_estimate_context()); break; case IB_WC_RDMA_WRITE: case IB_WC_RDMA_READ: