mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-21 20:51:27 +00:00
Automatic queue depth adjustment in scst_local
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4798 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -4472,4 +4472,7 @@ struct scst_data_descriptor {
|
||||
|
||||
void scst_write_same(struct scst_cmd *cmd);
|
||||
|
||||
__be64 scst_pack_lun(const uint64_t lun, enum scst_lun_addr_method addr_method);
|
||||
uint64_t scst_unpack_lun(const uint8_t *lun, int len);
|
||||
|
||||
#endif /* __SCST_H */
|
||||
|
||||
@@ -6889,6 +6889,7 @@ __be64 scst_pack_lun(const uint64_t lun, enum scst_lun_addr_method addr_method)
|
||||
TRACE_EXIT_HRES(res >> 48);
|
||||
return cpu_to_be64(res);
|
||||
}
|
||||
EXPORT_SYMBOL(scst_pack_lun);
|
||||
|
||||
/*
|
||||
* Function to extract a LUN number from an 8-byte LUN structure in network byte
|
||||
@@ -6951,6 +6952,7 @@ out_err:
|
||||
PRINT_ERROR("%s", "Multi-level LUN unimplemented");
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL(scst_unpack_lun);
|
||||
|
||||
/**
|
||||
** Generic parse() support routines.
|
||||
|
||||
@@ -391,9 +391,6 @@ int scst_alloc_space(struct scst_cmd *cmd);
|
||||
int scst_lib_init(void);
|
||||
void scst_lib_exit(void);
|
||||
|
||||
__be64 scst_pack_lun(const uint64_t lun, enum scst_lun_addr_method addr_method);
|
||||
uint64_t scst_unpack_lun(const uint8_t *lun, int len);
|
||||
|
||||
struct scst_mgmt_cmd *scst_alloc_mgmt_cmd(gfp_t gfp_mask);
|
||||
void scst_free_mgmt_cmd(struct scst_mgmt_cmd *mcmd);
|
||||
void scst_done_cmd_mgmt(struct scst_cmd *cmd);
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
#include <scst_debug.h>
|
||||
#endif
|
||||
|
||||
#ifndef RHEL_RELEASE_VERSION
|
||||
#define RHEL_RELEASE_VERSION(maj, min) 0
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
|
||||
#define SG_MAX_SINGLE_ALLOC (PAGE_SIZE / sizeof(struct scatterlist))
|
||||
#endif
|
||||
@@ -870,7 +874,7 @@ static int scst_local_target_reset(struct scsi_cmnd *SCpnt)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void copy_sense(struct scsi_cmnd *cmnd, struct scst_cmd *scst_cmnd)
|
||||
static void scst_local_copy_sense(struct scsi_cmnd *cmnd, struct scst_cmd *scst_cmnd)
|
||||
{
|
||||
int scst_cmnd_sense_len = scst_cmd_get_sense_buffer_len(scst_cmnd);
|
||||
|
||||
@@ -906,7 +910,7 @@ static int scst_local_send_resp(struct scsi_cmnd *cmnd,
|
||||
|
||||
/* Simulate autosense by this driver */
|
||||
if (unlikely(scst_sense_valid(scst_cmnd->sense)))
|
||||
copy_sense(cmnd, scst_cmnd);
|
||||
scst_local_copy_sense(cmnd, scst_cmnd);
|
||||
}
|
||||
|
||||
cmnd->result = scsi_result;
|
||||
@@ -1124,6 +1128,102 @@ static int scst_local_targ_pre_exec(struct scst_cmd *scst_cmd)
|
||||
return res;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) || \
|
||||
defined(CONFIG_SUSE_KERNEL) || \
|
||||
!(!defined(RHEL_RELEASE_CODE) || \
|
||||
RHEL_RELEASE_CODE -0 < RHEL_RELEASE_VERSION(6, 1))
|
||||
|
||||
static int scst_local_get_max_queue_depth(struct scsi_device *sdev)
|
||||
{
|
||||
int res;
|
||||
struct scst_local_sess *sess;
|
||||
__be16 lun;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
sess = to_scst_lcl_sess(scsi_get_device(sdev->host));
|
||||
lun = cpu_to_be16(sdev->lun);
|
||||
res = scst_get_max_lun_commands(sess->scst_sess,
|
||||
scst_unpack_lun((const uint8_t *)&lun, sizeof(lun)));
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int scst_local_change_queue_depth(struct scsi_device *sdev, int depth,
|
||||
int reason)
|
||||
{
|
||||
int res, mqd;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
switch (reason) {
|
||||
case SCSI_QDEPTH_DEFAULT:
|
||||
mqd = scst_local_get_max_queue_depth(sdev);
|
||||
if (mqd < depth) {
|
||||
PRINT_INFO("Requested queue depth %d is too big "
|
||||
"(possible max %d (sdev %p)", depth, mqd, sdev);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
PRINT_INFO("Setting queue depth %d as default (sdev %p, "
|
||||
"current %d)", depth, sdev, sdev->queue_depth);
|
||||
scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
|
||||
break;
|
||||
|
||||
case SCSI_QDEPTH_QFULL:
|
||||
TRACE(TRACE_FLOW_CONTROL, "QUEUE FULL on sdev %p, setting "
|
||||
"qdepth %d (cur %d)", sdev, depth, sdev->queue_depth);
|
||||
scsi_track_queue_full(sdev, depth);
|
||||
break;
|
||||
|
||||
case SCSI_QDEPTH_RAMP_UP:
|
||||
TRACE(TRACE_FLOW_CONTROL, "Ramping up qdepth on sdev %p to %d "
|
||||
"(cur %d)", sdev, depth, sdev->queue_depth);
|
||||
scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
|
||||
break;
|
||||
|
||||
default:
|
||||
res = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = sdev->queue_depth;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int scst_local_slave_alloc(struct scsi_device *sdev)
|
||||
{
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_BIDI, sdev->request_queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scst_local_slave_configure(struct scsi_device *sdev)
|
||||
{
|
||||
int mqd;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
mqd = scst_local_get_max_queue_depth(sdev);
|
||||
|
||||
PRINT_INFO("Configuring queue depth %d on sdev %p (tagged supported %d)",
|
||||
mqd, sdev, sdev->tagged_supported);
|
||||
|
||||
if (sdev->tagged_supported)
|
||||
scsi_activate_tcq(sdev, mqd);
|
||||
else
|
||||
scsi_deactivate_tcq(sdev, mqd);
|
||||
|
||||
TRACE_EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) && !defined(CONFIG_SUSE_KERNEL) && (!defined(RHEL_RELEASE_CODE) || RHEL_RELEASE_CODE -0 < RHEL_RELEASE_VERSION(6, 1)) */
|
||||
|
||||
/* Must be called under sess->aen_lock. Drops then reacquires it inside. */
|
||||
static void scst_process_aens(struct scst_local_sess *sess,
|
||||
bool cleanup_only)
|
||||
@@ -1426,16 +1526,37 @@ static struct scsi_host_template scst_lcl_ini_driver_template = {
|
||||
.queuecommand = scst_local_queuecommand_lck,
|
||||
#else
|
||||
.queuecommand = scst_local_queuecommand,
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) || \
|
||||
defined(CONFIG_SUSE_KERNEL) || \
|
||||
!(!defined(RHEL_RELEASE_CODE) || \
|
||||
RHEL_RELEASE_CODE -0 < RHEL_RELEASE_VERSION(6, 1))
|
||||
.change_queue_depth = scst_local_change_queue_depth,
|
||||
.slave_alloc = scst_local_slave_alloc,
|
||||
.slave_configure = scst_local_slave_configure,
|
||||
#endif
|
||||
.eh_abort_handler = scst_local_abort,
|
||||
.eh_device_reset_handler = scst_local_device_reset,
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25))
|
||||
.eh_target_reset_handler = scst_local_target_reset,
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33) || \
|
||||
defined(CONFIG_SUSE_KERNEL) || \
|
||||
!(!defined(RHEL_RELEASE_CODE) || \
|
||||
RHEL_RELEASE_CODE -0 < RHEL_RELEASE_VERSION(6, 1))
|
||||
.can_queue = 2048,
|
||||
/*
|
||||
* Set it low for the "Drop back to untagged" case in
|
||||
* scsi_track_queue_full(). We are adjusting it to a better
|
||||
* default in slave_configure()
|
||||
*/
|
||||
.cmd_per_lun = 3,
|
||||
#else
|
||||
.can_queue = 256,
|
||||
.cmd_per_lun = 32,
|
||||
#endif
|
||||
.this_id = -1,
|
||||
.sg_tablesize = 0xFFFF,
|
||||
.cmd_per_lun = 32,
|
||||
.max_sectors = 0xffff,
|
||||
/* Possible pass-through backend device may not support clustering */
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
|
||||
Reference in New Issue
Block a user