target: remove the transport_qf_callback se_cmd callback
Remove the need for the transport_qf_callback callback by making sure we have specific states with specific handlers for the two queue full cases. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
committed by
Nicholas Bellinger
parent
f55918fa32
commit
e057f53308
@@ -72,9 +72,8 @@ static int transport_generic_write_pending(struct se_cmd *);
|
|||||||
static int transport_processing_thread(void *param);
|
static int transport_processing_thread(void *param);
|
||||||
static int __transport_execute_tasks(struct se_device *dev);
|
static int __transport_execute_tasks(struct se_device *dev);
|
||||||
static void transport_complete_task_attr(struct se_cmd *cmd);
|
static void transport_complete_task_attr(struct se_cmd *cmd);
|
||||||
static int transport_complete_qf(struct se_cmd *cmd);
|
|
||||||
static void transport_handle_queue_full(struct se_cmd *cmd,
|
static void transport_handle_queue_full(struct se_cmd *cmd,
|
||||||
struct se_device *dev, int (*qf_callback)(struct se_cmd *));
|
struct se_device *dev);
|
||||||
static void transport_direct_request_timeout(struct se_cmd *cmd);
|
static void transport_direct_request_timeout(struct se_cmd *cmd);
|
||||||
static void transport_free_dev_tasks(struct se_cmd *cmd);
|
static void transport_free_dev_tasks(struct se_cmd *cmd);
|
||||||
static u32 transport_allocate_tasks(struct se_cmd *cmd,
|
static u32 transport_allocate_tasks(struct se_cmd *cmd,
|
||||||
@@ -969,7 +968,7 @@ static void target_qf_do_work(struct work_struct *work)
|
|||||||
|
|
||||||
pr_debug("Processing %s cmd: %p QUEUE_FULL in work queue"
|
pr_debug("Processing %s cmd: %p QUEUE_FULL in work queue"
|
||||||
" context: %s\n", cmd->se_tfo->get_fabric_name(), cmd,
|
" context: %s\n", cmd->se_tfo->get_fabric_name(), cmd,
|
||||||
(cmd->t_state == TRANSPORT_COMPLETE_OK) ? "COMPLETE_OK" :
|
(cmd->t_state == TRANSPORT_COMPLETE_QF_OK) ? "COMPLETE_OK" :
|
||||||
(cmd->t_state == TRANSPORT_COMPLETE_QF_WP) ? "WRITE_PENDING"
|
(cmd->t_state == TRANSPORT_COMPLETE_QF_WP) ? "WRITE_PENDING"
|
||||||
: "UNKNOWN");
|
: "UNKNOWN");
|
||||||
/*
|
/*
|
||||||
@@ -1968,8 +1967,8 @@ check_stop:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
queue_full:
|
queue_full:
|
||||||
cmd->t_state = TRANSPORT_COMPLETE_OK;
|
cmd->t_state = TRANSPORT_COMPLETE_QF_OK;
|
||||||
transport_handle_queue_full(cmd, cmd->se_dev, transport_complete_qf);
|
transport_handle_queue_full(cmd, cmd->se_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transport_direct_request_timeout(struct se_cmd *cmd)
|
static void transport_direct_request_timeout(struct se_cmd *cmd)
|
||||||
@@ -3431,12 +3430,19 @@ static void transport_complete_task_attr(struct se_cmd *cmd)
|
|||||||
wake_up_interruptible(&dev->dev_queue_obj.thread_wq);
|
wake_up_interruptible(&dev->dev_queue_obj.thread_wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int transport_complete_qf(struct se_cmd *cmd)
|
static void transport_complete_qf(struct se_cmd *cmd)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)
|
transport_stop_all_task_timers(cmd);
|
||||||
return cmd->se_tfo->queue_status(cmd);
|
if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
|
||||||
|
transport_complete_task_attr(cmd);
|
||||||
|
|
||||||
|
if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) {
|
||||||
|
ret = cmd->se_tfo->queue_status(cmd);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
switch (cmd->data_direction) {
|
switch (cmd->data_direction) {
|
||||||
case DMA_FROM_DEVICE:
|
case DMA_FROM_DEVICE:
|
||||||
@@ -3446,7 +3452,7 @@ static int transport_complete_qf(struct se_cmd *cmd)
|
|||||||
if (cmd->t_bidi_data_sg) {
|
if (cmd->t_bidi_data_sg) {
|
||||||
ret = cmd->se_tfo->queue_data_in(cmd);
|
ret = cmd->se_tfo->queue_data_in(cmd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
break;
|
||||||
}
|
}
|
||||||
/* Fall through for DMA_TO_DEVICE */
|
/* Fall through for DMA_TO_DEVICE */
|
||||||
case DMA_NONE:
|
case DMA_NONE:
|
||||||
@@ -3456,17 +3462,21 @@ static int transport_complete_qf(struct se_cmd *cmd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
out:
|
||||||
|
if (ret < 0) {
|
||||||
|
transport_handle_queue_full(cmd, cmd->se_dev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
transport_lun_remove_cmd(cmd);
|
||||||
|
transport_cmd_check_stop_to_fabric(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transport_handle_queue_full(
|
static void transport_handle_queue_full(
|
||||||
struct se_cmd *cmd,
|
struct se_cmd *cmd,
|
||||||
struct se_device *dev,
|
struct se_device *dev)
|
||||||
int (*qf_callback)(struct se_cmd *))
|
|
||||||
{
|
{
|
||||||
spin_lock_irq(&dev->qf_cmd_lock);
|
spin_lock_irq(&dev->qf_cmd_lock);
|
||||||
cmd->se_cmd_flags |= SCF_EMULATE_QUEUE_FULL;
|
cmd->se_cmd_flags |= SCF_EMULATE_QUEUE_FULL;
|
||||||
cmd->transport_qf_callback = qf_callback;
|
|
||||||
list_add_tail(&cmd->se_qf_node, &cmd->se_dev->qf_cmd_list);
|
list_add_tail(&cmd->se_qf_node, &cmd->se_dev->qf_cmd_list);
|
||||||
atomic_inc(&dev->dev_qf_count);
|
atomic_inc(&dev->dev_qf_count);
|
||||||
smp_mb__after_atomic_inc();
|
smp_mb__after_atomic_inc();
|
||||||
@@ -3492,14 +3502,6 @@ static void transport_generic_complete_ok(struct se_cmd *cmd)
|
|||||||
if (atomic_read(&cmd->se_dev->dev_qf_count) != 0)
|
if (atomic_read(&cmd->se_dev->dev_qf_count) != 0)
|
||||||
schedule_work(&cmd->se_dev->qf_work_queue);
|
schedule_work(&cmd->se_dev->qf_work_queue);
|
||||||
|
|
||||||
if (cmd->transport_qf_callback) {
|
|
||||||
ret = cmd->transport_qf_callback(cmd);
|
|
||||||
if (ret < 0)
|
|
||||||
goto queue_full;
|
|
||||||
|
|
||||||
cmd->transport_qf_callback = NULL;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Check if we need to retrieve a sense buffer from
|
* Check if we need to retrieve a sense buffer from
|
||||||
* the struct se_cmd in question.
|
* the struct se_cmd in question.
|
||||||
@@ -3575,7 +3577,6 @@ static void transport_generic_complete_ok(struct se_cmd *cmd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
transport_lun_remove_cmd(cmd);
|
transport_lun_remove_cmd(cmd);
|
||||||
transport_cmd_check_stop_to_fabric(cmd);
|
transport_cmd_check_stop_to_fabric(cmd);
|
||||||
return;
|
return;
|
||||||
@@ -3583,7 +3584,8 @@ done:
|
|||||||
queue_full:
|
queue_full:
|
||||||
pr_debug("Handling complete_ok QUEUE_FULL: se_cmd: %p,"
|
pr_debug("Handling complete_ok QUEUE_FULL: se_cmd: %p,"
|
||||||
" data_direction: %d\n", cmd, cmd->data_direction);
|
" data_direction: %d\n", cmd, cmd->data_direction);
|
||||||
transport_handle_queue_full(cmd, cmd->se_dev, transport_complete_qf);
|
cmd->t_state = TRANSPORT_COMPLETE_QF_OK;
|
||||||
|
transport_handle_queue_full(cmd, cmd->se_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transport_free_dev_tasks(struct se_cmd *cmd)
|
static void transport_free_dev_tasks(struct se_cmd *cmd)
|
||||||
@@ -4110,15 +4112,15 @@ void transport_generic_process_write(struct se_cmd *cmd)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(transport_generic_process_write);
|
EXPORT_SYMBOL(transport_generic_process_write);
|
||||||
|
|
||||||
static int transport_write_pending_qf(struct se_cmd *cmd)
|
static void transport_write_pending_qf(struct se_cmd *cmd)
|
||||||
{
|
{
|
||||||
return cmd->se_tfo->write_pending(cmd);
|
if (cmd->se_tfo->write_pending(cmd) == -EAGAIN) {
|
||||||
|
pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n",
|
||||||
|
cmd);
|
||||||
|
transport_handle_queue_full(cmd, cmd->se_dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* transport_generic_write_pending():
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static int transport_generic_write_pending(struct se_cmd *cmd)
|
static int transport_generic_write_pending(struct se_cmd *cmd)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@@ -4128,17 +4130,6 @@ static int transport_generic_write_pending(struct se_cmd *cmd)
|
|||||||
cmd->t_state = TRANSPORT_WRITE_PENDING;
|
cmd->t_state = TRANSPORT_WRITE_PENDING;
|
||||||
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
|
spin_unlock_irqrestore(&cmd->t_state_lock, flags);
|
||||||
|
|
||||||
if (cmd->transport_qf_callback) {
|
|
||||||
ret = cmd->transport_qf_callback(cmd);
|
|
||||||
if (ret == -EAGAIN)
|
|
||||||
goto queue_full;
|
|
||||||
else if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
cmd->transport_qf_callback = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear the se_cmd for WRITE_PENDING status in order to set
|
* Clear the se_cmd for WRITE_PENDING status in order to set
|
||||||
* cmd->t_transport_active=0 so that transport_generic_handle_data
|
* cmd->t_transport_active=0 so that transport_generic_handle_data
|
||||||
@@ -4163,8 +4154,7 @@ static int transport_generic_write_pending(struct se_cmd *cmd)
|
|||||||
queue_full:
|
queue_full:
|
||||||
pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd);
|
pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd);
|
||||||
cmd->t_state = TRANSPORT_COMPLETE_QF_WP;
|
cmd->t_state = TRANSPORT_COMPLETE_QF_WP;
|
||||||
transport_handle_queue_full(cmd, cmd->se_dev,
|
transport_handle_queue_full(cmd, cmd->se_dev);
|
||||||
transport_write_pending_qf);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4851,7 +4841,10 @@ get_cmd:
|
|||||||
transport_generic_request_timeout(cmd);
|
transport_generic_request_timeout(cmd);
|
||||||
break;
|
break;
|
||||||
case TRANSPORT_COMPLETE_QF_WP:
|
case TRANSPORT_COMPLETE_QF_WP:
|
||||||
transport_generic_write_pending(cmd);
|
transport_write_pending_qf(cmd);
|
||||||
|
break;
|
||||||
|
case TRANSPORT_COMPLETE_QF_OK:
|
||||||
|
transport_complete_qf(cmd);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("Unknown t_state: %d deferred_t_state:"
|
pr_err("Unknown t_state: %d deferred_t_state:"
|
||||||
|
@@ -102,6 +102,7 @@ enum transport_state_table {
|
|||||||
TRANSPORT_NEW_CMD_MAP = 16,
|
TRANSPORT_NEW_CMD_MAP = 16,
|
||||||
TRANSPORT_FREE_CMD_INTR = 17,
|
TRANSPORT_FREE_CMD_INTR = 17,
|
||||||
TRANSPORT_COMPLETE_QF_WP = 18,
|
TRANSPORT_COMPLETE_QF_WP = 18,
|
||||||
|
TRANSPORT_COMPLETE_QF_OK = 19,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used for struct se_cmd->se_cmd_flags */
|
/* Used for struct se_cmd->se_cmd_flags */
|
||||||
@@ -471,7 +472,6 @@ struct se_cmd {
|
|||||||
struct target_core_fabric_ops *se_tfo;
|
struct target_core_fabric_ops *se_tfo;
|
||||||
int (*transport_emulate_cdb)(struct se_cmd *);
|
int (*transport_emulate_cdb)(struct se_cmd *);
|
||||||
void (*transport_complete_callback)(struct se_cmd *);
|
void (*transport_complete_callback)(struct se_cmd *);
|
||||||
int (*transport_qf_callback)(struct se_cmd *);
|
|
||||||
|
|
||||||
unsigned char *t_task_cdb;
|
unsigned char *t_task_cdb;
|
||||||
unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE];
|
unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE];
|
||||||
|
Reference in New Issue
Block a user