aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2011-10-09 05:19:01 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2011-10-23 23:20:59 -0400
commitce8762f6cd1e0e6d87a6d0b536635993aef0a697 (patch)
treee59be88ea03a2b315afffad194a23b3ff1c652bc /drivers/target
parent8dc52b54207f361f7abf6cbe26f5199ae8b7cf23 (diff)
target: Remove legacy + unused device active I/O shutdown code
This patch removes the legacy device active I/O shutdown code that was originally called from transport_processing_thread() context during shutdown including transport_processing_shutdown() and transport_release_all_cmds(). This is due to the fact that in modern configfs control plane code by the time shutdown of an se_device instance in transport_processing_thread() is allowed to occur via: rmdir /sys/kernel/config/target/core/$HBA/$DEV all active I/O will already have been ceased while removing active configfs fabric Port/LUN symlinks. Eg: the removal of an active se_device is protected by inter-module VFS references from active Port/LUN symlinks. Two WARN_ON() checks have been added in their place before exiting transport_processing_thread() to watch out for any leaked descriptors. Cc: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_transport.c220
1 files changed, 2 insertions, 218 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 36fb39c2ce03..ee73f1095a12 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1040,41 +1040,6 @@ void transport_dump_dev_state(
1040 *bl += sprintf(b + *bl, " "); 1040 *bl += sprintf(b + *bl, " ");
1041} 1041}
1042 1042
1043/* transport_release_all_cmds():
1044 *
1045 *
1046 */
1047static void transport_release_all_cmds(struct se_device *dev)
1048{
1049 struct se_cmd *cmd, *tcmd;
1050 int bug_out = 0, t_state;
1051 unsigned long flags;
1052
1053 spin_lock_irqsave(&dev->dev_queue_obj.cmd_queue_lock, flags);
1054 list_for_each_entry_safe(cmd, tcmd, &dev->dev_queue_obj.qobj_list,
1055 se_queue_node) {
1056 t_state = cmd->t_state;
1057 list_del_init(&cmd->se_queue_node);
1058 spin_unlock_irqrestore(&dev->dev_queue_obj.cmd_queue_lock,
1059 flags);
1060
1061 pr_err("Releasing ITT: 0x%08x, i_state: %u,"
1062 " t_state: %u directly\n",
1063 cmd->se_tfo->get_task_tag(cmd),
1064 cmd->se_tfo->get_cmd_state(cmd), t_state);
1065
1066 transport_put_cmd(cmd);
1067 bug_out = 1;
1068
1069 spin_lock_irqsave(&dev->dev_queue_obj.cmd_queue_lock, flags);
1070 }
1071 spin_unlock_irqrestore(&dev->dev_queue_obj.cmd_queue_lock, flags);
1072#if 0
1073 if (bug_out)
1074 BUG();
1075#endif
1076}
1077
1078void transport_dump_vpd_proto_id( 1043void transport_dump_vpd_proto_id(
1079 struct t10_vpd *vpd, 1044 struct t10_vpd *vpd,
1080 unsigned char *p_buf, 1045 unsigned char *p_buf,
@@ -4859,180 +4824,6 @@ int transport_generic_do_tmr(struct se_cmd *cmd)
4859 return 0; 4824 return 0;
4860} 4825}
4861 4826
4862/*
4863 * Called with spin_lock_irq(&dev->execute_task_lock); held
4864 *
4865 */
4866static struct se_task *
4867transport_get_task_from_state_list(struct se_device *dev)
4868{
4869 struct se_task *task;
4870
4871 if (list_empty(&dev->state_task_list))
4872 return NULL;
4873
4874 list_for_each_entry(task, &dev->state_task_list, t_state_list)
4875 break;
4876
4877 list_del(&task->t_state_list);
4878 atomic_set(&task->task_state_active, 0);
4879
4880 return task;
4881}
4882
4883static void transport_processing_shutdown(struct se_device *dev)
4884{
4885 struct se_cmd *cmd;
4886 struct se_task *task;
4887 unsigned long flags;
4888 /*
4889 * Empty the struct se_device's struct se_task state list.
4890 */
4891 spin_lock_irqsave(&dev->execute_task_lock, flags);
4892 while ((task = transport_get_task_from_state_list(dev))) {
4893 if (!task->task_se_cmd) {
4894 pr_err("task->task_se_cmd is NULL!\n");
4895 continue;
4896 }
4897 cmd = task->task_se_cmd;
4898
4899 spin_unlock_irqrestore(&dev->execute_task_lock, flags);
4900
4901 spin_lock_irqsave(&cmd->t_state_lock, flags);
4902
4903 pr_debug("PT: cmd: %p task: %p ITT: 0x%08x,"
4904 " i_state: %d, t_state/def_t_state:"
4905 " %d/%d cdb: 0x%02x\n", cmd, task,
4906 cmd->se_tfo->get_task_tag(cmd),
4907 cmd->se_tfo->get_cmd_state(cmd),
4908 cmd->t_state, cmd->deferred_t_state,
4909 cmd->t_task_cdb[0]);
4910 pr_debug("PT: ITT[0x%08x] - t_tasks: %d t_task_cdbs_left:"
4911 " %d t_task_cdbs_sent: %d -- t_transport_active: %d"
4912 " t_transport_stop: %d t_transport_sent: %d\n",
4913 cmd->se_tfo->get_task_tag(cmd),
4914 cmd->t_task_list_num,
4915 atomic_read(&cmd->t_task_cdbs_left),
4916 atomic_read(&cmd->t_task_cdbs_sent),
4917 atomic_read(&cmd->t_transport_active),
4918 atomic_read(&cmd->t_transport_stop),
4919 atomic_read(&cmd->t_transport_sent));
4920
4921 if (atomic_read(&task->task_active)) {
4922 atomic_set(&task->task_stop, 1);
4923 spin_unlock_irqrestore(
4924 &cmd->t_state_lock, flags);
4925
4926 pr_debug("Waiting for task: %p to shutdown for dev:"
4927 " %p\n", task, dev);
4928 wait_for_completion(&task->task_stop_comp);
4929 pr_debug("Completed task: %p shutdown for dev: %p\n",
4930 task, dev);
4931
4932 spin_lock_irqsave(&cmd->t_state_lock, flags);
4933 atomic_dec(&cmd->t_task_cdbs_left);
4934
4935 atomic_set(&task->task_active, 0);
4936 atomic_set(&task->task_stop, 0);
4937 } else {
4938 if (atomic_read(&task->task_execute_queue) != 0)
4939 transport_remove_task_from_execute_queue(task, dev);
4940 }
4941 __transport_stop_task_timer(task, &flags);
4942
4943 if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) {
4944 spin_unlock_irqrestore(
4945 &cmd->t_state_lock, flags);
4946
4947 pr_debug("Skipping task: %p, dev: %p for"
4948 " t_task_cdbs_ex_left: %d\n", task, dev,
4949 atomic_read(&cmd->t_task_cdbs_ex_left));
4950
4951 spin_lock_irqsave(&dev->execute_task_lock, flags);
4952 continue;
4953 }
4954
4955 if (atomic_read(&cmd->t_transport_active)) {
4956 pr_debug("got t_transport_active = 1 for task: %p, dev:"
4957 " %p\n", task, dev);
4958
4959 if (atomic_read(&cmd->t_fe_count)) {
4960 spin_unlock_irqrestore(
4961 &cmd->t_state_lock, flags);
4962 transport_send_check_condition_and_sense(
4963 cmd, TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE,
4964 0);
4965 transport_remove_cmd_from_queue(cmd,
4966 &cmd->se_dev->dev_queue_obj);
4967
4968 transport_lun_remove_cmd(cmd);
4969 transport_cmd_check_stop(cmd, 1, 0);
4970 } else {
4971 spin_unlock_irqrestore(
4972 &cmd->t_state_lock, flags);
4973
4974 transport_remove_cmd_from_queue(cmd,
4975 &cmd->se_dev->dev_queue_obj);
4976
4977 transport_lun_remove_cmd(cmd);
4978
4979 if (transport_cmd_check_stop(cmd, 1, 0))
4980 transport_put_cmd(cmd);
4981 }
4982
4983 spin_lock_irqsave(&dev->execute_task_lock, flags);
4984 continue;
4985 }
4986 pr_debug("Got t_transport_active = 0 for task: %p, dev: %p\n",
4987 task, dev);
4988
4989 if (atomic_read(&cmd->t_fe_count)) {
4990 spin_unlock_irqrestore(
4991 &cmd->t_state_lock, flags);
4992 transport_send_check_condition_and_sense(cmd,
4993 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
4994 transport_remove_cmd_from_queue(cmd,
4995 &cmd->se_dev->dev_queue_obj);
4996
4997 transport_lun_remove_cmd(cmd);
4998 transport_cmd_check_stop(cmd, 1, 0);
4999 } else {
5000 spin_unlock_irqrestore(
5001 &cmd->t_state_lock, flags);
5002
5003 transport_remove_cmd_from_queue(cmd,
5004 &cmd->se_dev->dev_queue_obj);
5005 transport_lun_remove_cmd(cmd);
5006
5007 if (transport_cmd_check_stop(cmd, 1, 0))
5008 transport_put_cmd(cmd);
5009 }
5010
5011 spin_lock_irqsave(&dev->execute_task_lock, flags);
5012 }
5013 spin_unlock_irqrestore(&dev->execute_task_lock, flags);
5014 /*
5015 * Empty the struct se_device's struct se_cmd list.
5016 */
5017 while ((cmd = transport_get_cmd_from_queue(&dev->dev_queue_obj))) {
5018
5019 pr_debug("From Device Queue: cmd: %p t_state: %d\n",
5020 cmd, cmd->t_state);
5021
5022 if (atomic_read(&cmd->t_fe_count)) {
5023 transport_send_check_condition_and_sense(cmd,
5024 TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
5025
5026 transport_lun_remove_cmd(cmd);
5027 transport_cmd_check_stop(cmd, 1, 0);
5028 } else {
5029 transport_lun_remove_cmd(cmd);
5030 if (transport_cmd_check_stop(cmd, 1, 0))
5031 transport_put_cmd(cmd);
5032 }
5033 }
5034}
5035
5036/* transport_processing_thread(): 4827/* transport_processing_thread():
5037 * 4828 *
5038 * 4829 *
@@ -5052,14 +4843,6 @@ static int transport_processing_thread(void *param)
5052 if (ret < 0) 4843 if (ret < 0)
5053 goto out; 4844 goto out;
5054 4845
5055 spin_lock_irq(&dev->dev_status_lock);
5056 if (dev->dev_status & TRANSPORT_DEVICE_SHUTDOWN) {
5057 spin_unlock_irq(&dev->dev_status_lock);
5058 transport_processing_shutdown(dev);
5059 continue;
5060 }
5061 spin_unlock_irq(&dev->dev_status_lock);
5062
5063get_cmd: 4846get_cmd:
5064 __transport_execute_tasks(dev); 4847 __transport_execute_tasks(dev);
5065 4848
@@ -5135,7 +4918,8 @@ get_cmd:
5135 } 4918 }
5136 4919
5137out: 4920out:
5138 transport_release_all_cmds(dev); 4921 WARN_ON(!list_empty(&dev->state_task_list));
4922 WARN_ON(!list_empty(&dev->dev_queue_obj.qobj_list));
5139 dev->process_thread = NULL; 4923 dev->process_thread = NULL;
5140 return 0; 4924 return 0;
5141} 4925}