From e2639613c5f21aadb305625cf73ed14d050e15b8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Feb 2019 03:40:48 +0000 Subject: [PATCH 1/2] scst: Introduce scst_handle_aca() Move the ACA code out of __scst_init_cmd() to make __scst_init_cmd() easier to read. This patch does not change any functionality. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7923 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_targ.c | 164 +++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 78 deletions(-) diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 617cc3cbb..58b12d43f 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -5036,6 +5036,89 @@ static int scst_translate_lun(struct scst_cmd *cmd) return res; } +static void scst_handle_aca(struct scst_cmd *cmd) +{ + struct scst_order_data *order_data = cmd->cur_order_data; + unsigned long flags; + +again: + if (unlikely(order_data->aca_tgt_dev != 0)) { + spin_lock_irqsave(&order_data->sn_lock, flags); + if (order_data->aca_tgt_dev == 0) { + spin_unlock_irqrestore(&order_data->sn_lock, flags); + goto again; + } + + if (order_data->aca_tgt_dev == (unsigned long)cmd->tgt_dev) { + if (cmd->queue_type != SCST_CMD_QUEUE_ACA || + order_data->aca_cmd || cmd->dev->tmf_only) { + TRACE_DBG("Refusing cmd %p, because ACA active (aca_cmd %p, tgt_dev %p)", + cmd, order_data->aca_cmd, + cmd->tgt_dev); + goto out_unlock_aca_active; + } else { + TRACE_MGMT_DBG("ACA cmd %p (tgt_dev %p)", + cmd, cmd->tgt_dev); + order_data->aca_cmd = cmd; + /* allow it */ + } + } else { + /* Non-faulted I_T nexus */ + EXTRACHECKS_BUG_ON(cmd->dev->tst != + SCST_TST_0_SINGLE_TASK_SET); + if (cmd->queue_type == SCST_CMD_QUEUE_ACA) { + TRACE_MGMT_DBG("Refusing ACA cmd %p from wrong I_T nexus (aca_tgt_dev %ld, cmd->tgt_dev %p)", + cmd, order_data->aca_tgt_dev, + cmd->tgt_dev); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_message)); + goto out_unlock_aca_active; + } else { + if (cmd->cdb[0] == PERSISTENT_RESERVE_OUT && + (cmd->cdb[1] & 0x1f) == + PR_PREEMPT_AND_ABORT) { + TRACE_MGMT_DBG("Allow PR PREEMPT AND ABORT cmd %p during ACA (tgt_dev %p)", + cmd, cmd->tgt_dev); + /* allow it */ + } else { + TRACE_DBG("Refusing other IT-nexus cmd %p, because ACA active (tgt_dev %p)", + cmd, cmd->tgt_dev); + if (cmd->cmd_naca) + goto out_unlock_aca_active; + else { + spin_unlock_irqrestore(&order_data->sn_lock, flags); + scst_set_cmd_error_status(cmd, SAM_STAT_BUSY); + goto out_bypass_aca; + } + } + } + } + + cmd->cmd_aca_allowed = 1; + + spin_unlock_irqrestore(&order_data->sn_lock, flags); + } else if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_ACA)) { + TRACE_MGMT_DBG("Refusing ACA cmd %p, because there's no ACA, tgt_dev %p", + cmd, cmd->tgt_dev); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_message)); + goto out_abnormal; + } + + return; + +out_unlock_aca_active: + spin_unlock_irqrestore(&order_data->sn_lock, flags); + scst_set_cmd_error_status(cmd, SAM_STAT_ACA_ACTIVE); + +out_bypass_aca: + cmd->cmd_aca_allowed = 1; /* for check in scst_pre_xmit_response2() */ + +out_abnormal: + scst_set_cmd_abnormal_done_state(cmd); + return; +} + /* * No locks, but might be on IRQ. * @@ -5045,8 +5128,6 @@ static int scst_translate_lun(struct scst_cmd *cmd) static int __scst_init_cmd(struct scst_cmd *cmd) { int res = 0; - unsigned long flags; - struct scst_order_data *order_data; TRACE_ENTRY(); @@ -5055,8 +5136,6 @@ static int __scst_init_cmd(struct scst_cmd *cmd) int cnt; bool failure = false; - order_data = cmd->cur_order_data; - scst_set_cmd_state(cmd, SCST_CMD_STATE_PARSE); cnt = atomic_inc_return(&cmd->tgt_dev->tgt_dev_cmd_count); @@ -5102,73 +5181,9 @@ static int __scst_init_cmd(struct scst_cmd *cmd) * queue_type to change it if needed. ToDo. */ scst_pre_parse(cmd); -again: - if (unlikely(order_data->aca_tgt_dev != 0)) { - spin_lock_irqsave(&order_data->sn_lock, flags); - - if (order_data->aca_tgt_dev == 0) { - spin_unlock_irqrestore(&order_data->sn_lock, flags); - goto again; - } - - if (order_data->aca_tgt_dev == (unsigned long)cmd->tgt_dev) { - if ((cmd->queue_type != SCST_CMD_QUEUE_ACA) || - (order_data->aca_cmd != NULL) || - cmd->dev->tmf_only) { - TRACE_DBG("Refusing cmd %p, because ACA " - "active (aca_cmd %p, tgt_dev %p)", - cmd, order_data->aca_cmd, - cmd->tgt_dev); - goto out_unlock_aca_active; - } else { - TRACE_MGMT_DBG("ACA cmd %p (tgt_dev %p)", - cmd, cmd->tgt_dev); - order_data->aca_cmd = cmd; - /* allow it */ - } - } else { - /* Non-faulted I_T nexus */ - EXTRACHECKS_BUG_ON(cmd->dev->tst != SCST_TST_0_SINGLE_TASK_SET); - if (cmd->queue_type == SCST_CMD_QUEUE_ACA) { - TRACE_MGMT_DBG("Refusing ACA cmd %p " - "from wrong I_T nexus (aca_tgt_dev %ld, " - "cmd->tgt_dev %p)", cmd, - order_data->aca_tgt_dev, cmd->tgt_dev); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_message)); - goto out_unlock_aca_active; - } else { - if ((cmd->cdb[0] == PERSISTENT_RESERVE_OUT) && - ((cmd->cdb[1] & 0x1f) == PR_PREEMPT_AND_ABORT)) { - TRACE_MGMT_DBG("Allow PR PREEMPT AND " - "ABORT cmd %p during ACA " - "(tgt_dev %p)", cmd, cmd->tgt_dev); - /* allow it */ - } else { - TRACE_DBG("Refusing other IT-nexus " - "cmd %p, because ACA active " - "(tgt_dev %p)", cmd, cmd->tgt_dev); - if (cmd->cmd_naca) - goto out_unlock_aca_active; - else { - spin_unlock_irqrestore(&order_data->sn_lock, flags); - scst_set_cmd_error_status(cmd, SAM_STAT_BUSY); - goto out_bypass_aca; - } - } - } - } - - cmd->cmd_aca_allowed = 1; - - spin_unlock_irqrestore(&order_data->sn_lock, flags); - } else if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_ACA)) { - TRACE_MGMT_DBG("Refusing ACA cmd %p, because there's no ACA, " - "tgt_dev %p", cmd, cmd->tgt_dev); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_message)); - goto out_abnormal; - } + scst_handle_aca(cmd); + if (cmd->completed) + goto out; if (!cmd->set_sn_on_restart_cmd) { if (!cmd->tgtt->multithreaded_init_done) @@ -5194,18 +5209,11 @@ out: out_busy_bypass_aca: scst_set_busy(cmd); - -out_bypass_aca: cmd->cmd_aca_allowed = 1; /* for check in scst_pre_xmit_response2() */ out_abnormal: scst_set_cmd_abnormal_done_state(cmd); goto out; - -out_unlock_aca_active: - spin_unlock_irqrestore(&order_data->sn_lock, flags); - scst_set_cmd_error_status(cmd, SAM_STAT_ACA_ACTIVE); - goto out_bypass_aca; } /* Called under scst_init_lock and IRQs disabled */ From 81e904c75088186bda3d9d797620ba3a51ed46ab Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 12 Feb 2019 03:41:16 +0000 Subject: [PATCH 2/2] scst: Rework scst_handle_aca() Make sure that the code that is in the hot path occurs first. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7924 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_targ.c | 109 +++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 55 deletions(-) diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 58b12d43f..1e315e06f 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -5042,69 +5042,70 @@ static void scst_handle_aca(struct scst_cmd *cmd) unsigned long flags; again: - if (unlikely(order_data->aca_tgt_dev != 0)) { - spin_lock_irqsave(&order_data->sn_lock, flags); - if (order_data->aca_tgt_dev == 0) { - spin_unlock_irqrestore(&order_data->sn_lock, flags); - goto again; + if (likely(!order_data->aca_tgt_dev)) { + if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_ACA)) { + TRACE_MGMT_DBG("Refusing ACA cmd %p, because there's no ACA, tgt_dev %p", + cmd, cmd->tgt_dev); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_message)); + scst_set_cmd_abnormal_done_state(cmd); } + return; + } - if (order_data->aca_tgt_dev == (unsigned long)cmd->tgt_dev) { - if (cmd->queue_type != SCST_CMD_QUEUE_ACA || - order_data->aca_cmd || cmd->dev->tmf_only) { - TRACE_DBG("Refusing cmd %p, because ACA active (aca_cmd %p, tgt_dev %p)", - cmd, order_data->aca_cmd, - cmd->tgt_dev); - goto out_unlock_aca_active; - } else { - TRACE_MGMT_DBG("ACA cmd %p (tgt_dev %p)", - cmd, cmd->tgt_dev); - order_data->aca_cmd = cmd; - /* allow it */ - } + spin_lock_irqsave(&order_data->sn_lock, flags); + if (!order_data->aca_tgt_dev) { + spin_unlock_irqrestore(&order_data->sn_lock, flags); + goto again; + } + + if (order_data->aca_tgt_dev == (unsigned long)cmd->tgt_dev) { + if (cmd->queue_type != SCST_CMD_QUEUE_ACA || + order_data->aca_cmd || cmd->dev->tmf_only) { + TRACE_DBG("Refusing cmd %p, because ACA active (aca_cmd %p, tgt_dev %p)", + cmd, order_data->aca_cmd, + cmd->tgt_dev); + goto out_unlock_aca_active; } else { - /* Non-faulted I_T nexus */ - EXTRACHECKS_BUG_ON(cmd->dev->tst != - SCST_TST_0_SINGLE_TASK_SET); - if (cmd->queue_type == SCST_CMD_QUEUE_ACA) { - TRACE_MGMT_DBG("Refusing ACA cmd %p from wrong I_T nexus (aca_tgt_dev %ld, cmd->tgt_dev %p)", - cmd, order_data->aca_tgt_dev, - cmd->tgt_dev); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_message)); - goto out_unlock_aca_active; + TRACE_MGMT_DBG("ACA cmd %p (tgt_dev %p)", + cmd, cmd->tgt_dev); + order_data->aca_cmd = cmd; + /* allow it */ + } + } else { + /* Non-faulted I_T nexus */ + EXTRACHECKS_BUG_ON(cmd->dev->tst != SCST_TST_0_SINGLE_TASK_SET); + if (cmd->queue_type == SCST_CMD_QUEUE_ACA) { + TRACE_MGMT_DBG("Refusing ACA cmd %p from wrong I_T nexus (aca_tgt_dev %ld, cmd->tgt_dev %p)", + cmd, order_data->aca_tgt_dev, + cmd->tgt_dev); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_message)); + goto out_unlock_aca_active; + } else { + if (cmd->cdb[0] == PERSISTENT_RESERVE_OUT && + (cmd->cdb[1] & 0x1f) == PR_PREEMPT_AND_ABORT) { + TRACE_MGMT_DBG("Allow PR PREEMPT AND ABORT cmd %p during ACA (tgt_dev %p)", + cmd, cmd->tgt_dev); + /* allow it */ } else { - if (cmd->cdb[0] == PERSISTENT_RESERVE_OUT && - (cmd->cdb[1] & 0x1f) == - PR_PREEMPT_AND_ABORT) { - TRACE_MGMT_DBG("Allow PR PREEMPT AND ABORT cmd %p during ACA (tgt_dev %p)", - cmd, cmd->tgt_dev); - /* allow it */ + TRACE_DBG("Refusing other IT-nexus cmd %p, because ACA active (tgt_dev %p)", + cmd, cmd->tgt_dev); + if (cmd->cmd_naca) { + goto out_unlock_aca_active; } else { - TRACE_DBG("Refusing other IT-nexus cmd %p, because ACA active (tgt_dev %p)", - cmd, cmd->tgt_dev); - if (cmd->cmd_naca) - goto out_unlock_aca_active; - else { - spin_unlock_irqrestore(&order_data->sn_lock, flags); - scst_set_cmd_error_status(cmd, SAM_STAT_BUSY); - goto out_bypass_aca; - } + spin_unlock_irqrestore(&order_data->sn_lock, flags); + scst_set_cmd_error_status(cmd, SAM_STAT_BUSY); + goto out_bypass_aca; } } } - - cmd->cmd_aca_allowed = 1; - - spin_unlock_irqrestore(&order_data->sn_lock, flags); - } else if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_ACA)) { - TRACE_MGMT_DBG("Refusing ACA cmd %p, because there's no ACA, tgt_dev %p", - cmd, cmd->tgt_dev); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_message)); - goto out_abnormal; } + cmd->cmd_aca_allowed = 1; + + spin_unlock_irqrestore(&order_data->sn_lock, flags); + return; out_unlock_aca_active: @@ -5113,8 +5114,6 @@ out_unlock_aca_active: out_bypass_aca: cmd->cmd_aca_allowed = 1; /* for check in scst_pre_xmit_response2() */ - -out_abnormal: scst_set_cmd_abnormal_done_state(cmd); return; }