Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[firefly-linux-kernel-4.4.55.git] / drivers / target / target_core_transport.c
index 21e315874a5472503dfe1ba010dea1236993b553..7172d005d063439999ddaa619ef0a96877b42cec 100644 (file)
@@ -52,6 +52,9 @@
 #include "target_core_pr.h"
 #include "target_core_ua.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/target.h>
+
 static struct workqueue_struct *target_completion_wq;
 static struct kmem_cache *se_sess_cache;
 struct kmem_cache *se_ua_cache;
@@ -446,11 +449,15 @@ static void target_remove_from_state_list(struct se_cmd *cmd)
        spin_unlock_irqrestore(&dev->execute_task_lock, flags);
 }
 
-static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists)
+static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists,
+                                   bool write_pending)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&cmd->t_state_lock, flags);
+       if (write_pending)
+               cmd->t_state = TRANSPORT_WRITE_PENDING;
+
        /*
         * Determine if IOCTL context caller in requesting the stopping of this
         * command for LUN shutdown purposes.
@@ -515,7 +522,7 @@ static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists)
 
 static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd)
 {
-       return transport_cmd_check_stop(cmd, true);
+       return transport_cmd_check_stop(cmd, true, false);
 }
 
 static void transport_lun_remove_cmd(struct se_cmd *cmd)
@@ -526,13 +533,6 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd)
        if (!lun)
                return;
 
-       spin_lock_irqsave(&cmd->t_state_lock, flags);
-       if (cmd->transport_state & CMD_T_DEV_ACTIVE) {
-               cmd->transport_state &= ~CMD_T_DEV_ACTIVE;
-               target_remove_from_state_list(cmd);
-       }
-       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-
        spin_lock_irqsave(&lun->lun_cmd_lock, flags);
        if (!list_empty(&cmd->se_lun_node))
                list_del_init(&cmd->se_lun_node);
@@ -1092,7 +1092,6 @@ sense_reason_t
 target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
 {
        struct se_device *dev = cmd->se_dev;
-       unsigned long flags;
        sense_reason_t ret;
 
        /*
@@ -1127,6 +1126,8 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
         */
        memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb));
 
+       trace_target_sequencer_start(cmd);
+
        /*
         * Check for an existing UNIT ATTENTION condition
         */
@@ -1152,9 +1153,7 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
        if (ret)
                return ret;
 
-       spin_lock_irqsave(&cmd->t_state_lock, flags);
        cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE;
-       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
        spin_lock(&cmd->se_lun->lun_sep_lock);
        if (cmd->se_lun->lun_sep)
@@ -1552,7 +1551,8 @@ void transport_generic_request_failure(struct se_cmd *cmd,
                                cmd->orig_fe_lun, 0x2C,
                                ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS);
 
-               ret = cmd->se_tfo->queue_status(cmd);
+               trace_target_cmd_complete(cmd);
+               ret = cmd->se_tfo-> queue_status(cmd);
                if (ret == -EAGAIN || ret == -ENOMEM)
                        goto queue_full;
                goto check_stop;
@@ -1583,10 +1583,6 @@ static void __target_execute_cmd(struct se_cmd *cmd)
 {
        sense_reason_t ret;
 
-       spin_lock_irq(&cmd->t_state_lock);
-       cmd->transport_state |= (CMD_T_BUSY|CMD_T_SENT);
-       spin_unlock_irq(&cmd->t_state_lock);
-
        if (cmd->execute_cmd) {
                ret = cmd->execute_cmd(cmd);
                if (ret) {
@@ -1693,11 +1689,17 @@ void target_execute_cmd(struct se_cmd *cmd)
        }
 
        cmd->t_state = TRANSPORT_PROCESSING;
-       cmd->transport_state |= CMD_T_ACTIVE;
+       cmd->transport_state |= CMD_T_ACTIVE|CMD_T_BUSY|CMD_T_SENT;
        spin_unlock_irq(&cmd->t_state_lock);
 
-       if (!target_handle_task_attr(cmd))
-               __target_execute_cmd(cmd);
+       if (target_handle_task_attr(cmd)) {
+               spin_lock_irq(&cmd->t_state_lock);
+               cmd->transport_state &= ~CMD_T_BUSY|CMD_T_SENT;
+               spin_unlock_irq(&cmd->t_state_lock);
+               return;
+       }
+
+       __target_execute_cmd(cmd);
 }
 EXPORT_SYMBOL(target_execute_cmd);
 
@@ -1770,6 +1772,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
        transport_complete_task_attr(cmd);
 
        if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) {
+               trace_target_cmd_complete(cmd);
                ret = cmd->se_tfo->queue_status(cmd);
                if (ret)
                        goto out;
@@ -1777,6 +1780,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
 
        switch (cmd->data_direction) {
        case DMA_FROM_DEVICE:
+               trace_target_cmd_complete(cmd);
                ret = cmd->se_tfo->queue_data_in(cmd);
                break;
        case DMA_TO_DEVICE:
@@ -1787,6 +1791,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
                }
                /* Fall through for DMA_TO_DEVICE */
        case DMA_NONE:
+               trace_target_cmd_complete(cmd);
                ret = cmd->se_tfo->queue_status(cmd);
                break;
        default:
@@ -1865,6 +1870,7 @@ static void target_complete_ok_work(struct work_struct *work)
                }
                spin_unlock(&cmd->se_lun->lun_sep_lock);
 
+               trace_target_cmd_complete(cmd);
                ret = cmd->se_tfo->queue_data_in(cmd);
                if (ret == -EAGAIN || ret == -ENOMEM)
                        goto queue_full;
@@ -1893,6 +1899,7 @@ static void target_complete_ok_work(struct work_struct *work)
                }
                /* Fall through for DMA_TO_DEVICE */
        case DMA_NONE:
+               trace_target_cmd_complete(cmd);
                ret = cmd->se_tfo->queue_status(cmd);
                if (ret == -EAGAIN || ret == -ENOMEM)
                        goto queue_full;
@@ -1956,11 +1963,7 @@ static int transport_release_cmd(struct se_cmd *cmd)
         * If this cmd has been setup with target_get_sess_cmd(), drop
         * the kref and call ->release_cmd() in kref callback.
         */
-        if (cmd->check_release != 0)
-               return target_put_sess_cmd(cmd->se_sess, cmd);
-
-       cmd->se_tfo->release_cmd(cmd);
-       return 1;
+       return target_put_sess_cmd(cmd->se_sess, cmd);
 }
 
 /**
@@ -1971,21 +1974,6 @@ static int transport_release_cmd(struct se_cmd *cmd)
  */
 static int transport_put_cmd(struct se_cmd *cmd)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&cmd->t_state_lock, flags);
-       if (atomic_read(&cmd->t_fe_count) &&
-           !atomic_dec_and_test(&cmd->t_fe_count)) {
-               spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               return 0;
-       }
-
-       if (cmd->transport_state & CMD_T_DEV_ACTIVE) {
-               cmd->transport_state &= ~CMD_T_DEV_ACTIVE;
-               target_remove_from_state_list(cmd);
-       }
-       spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-
        transport_free_pages(cmd);
        return transport_release_cmd(cmd);
 }
@@ -2103,9 +2091,6 @@ transport_generic_new_cmd(struct se_cmd *cmd)
                if (ret < 0)
                        return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
        }
-
-       atomic_inc(&cmd->t_fe_count);
-
        /*
         * If this command is not a write we can execute it right here,
         * for write buffers we need to notify the fabric driver first
@@ -2116,12 +2101,7 @@ transport_generic_new_cmd(struct se_cmd *cmd)
                target_execute_cmd(cmd);
                return 0;
        }
-
-       spin_lock_irq(&cmd->t_state_lock);
-       cmd->t_state = TRANSPORT_WRITE_PENDING;
-       spin_unlock_irq(&cmd->t_state_lock);
-
-       transport_cmd_check_stop(cmd, false);
+       transport_cmd_check_stop(cmd, false, true);
 
        ret = cmd->se_tfo->write_pending(cmd);
        if (ret == -EAGAIN || ret == -ENOMEM)
@@ -2202,8 +2182,6 @@ int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd,
                goto out;
        }
        list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list);
-       se_cmd->check_release = 1;
-
 out:
        spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
        return ret;
@@ -2319,7 +2297,7 @@ static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun)
                pr_debug("ConfigFS ITT[0x%08x] - CMD_T_STOP, skipping\n",
                         cmd->se_tfo->get_task_tag(cmd));
                spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-               transport_cmd_check_stop(cmd, false);
+               transport_cmd_check_stop(cmd, false, false);
                return -EPERM;
        }
        cmd->transport_state |= CMD_T_LUN_FE_STOP;
@@ -2427,7 +2405,7 @@ check_cond:
 
                        spin_unlock_irqrestore(&cmd->t_state_lock,
                                        cmd_flags);
-                       transport_cmd_check_stop(cmd, false);
+                       transport_cmd_check_stop(cmd, false, false);
                        complete(&cmd->transport_lun_fe_stop_comp);
                        spin_lock_irqsave(&lun->lun_cmd_lock, lun_flags);
                        continue;
@@ -2778,6 +2756,7 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd,
        cmd->scsi_sense_length  = TRANSPORT_SENSE_BUFFER;
 
 after_reason:
+       trace_target_cmd_complete(cmd);
        return cmd->se_tfo->queue_status(cmd);
 }
 EXPORT_SYMBOL(transport_send_check_condition_and_sense);
@@ -2794,6 +2773,7 @@ int transport_check_aborted_status(struct se_cmd *cmd, int send_status)
                 cmd->t_task_cdb[0], cmd->se_tfo->get_task_tag(cmd));
 
        cmd->se_cmd_flags |= SCF_SENT_DELAYED_TAS;
+       trace_target_cmd_complete(cmd);
        cmd->se_tfo->queue_status(cmd);
 
        return 1;
@@ -2831,6 +2811,7 @@ void transport_send_task_abort(struct se_cmd *cmd)
                " ITT: 0x%08x\n", cmd->t_task_cdb[0],
                cmd->se_tfo->get_task_tag(cmd));
 
+       trace_target_cmd_complete(cmd);
        cmd->se_tfo->queue_status(cmd);
 }