mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-20 20:21:30 +00:00
- Fixed BUG() with put_page_callback patch for network hardware without TX offload
- Fixed 2 corner cases crashes with disabled pass-through devices - Docs updated git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@205 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -52,7 +52,15 @@ original IET behavior, when for data transmission:
|
||||
data will be additionally copied into temporary TCP buffers. The
|
||||
performance hit will be quite noticeable.
|
||||
|
||||
If you have error messages like:
|
||||
Note, that if your network hardware does not support TX offload
|
||||
functions of has them disabled, then TCP zero-copy transmit functions on
|
||||
your system will not be used by Linux networking in any case, so
|
||||
put_page_callback patch will not be able to improve performance for you.
|
||||
You can check your network hardware offload capabilities by command
|
||||
"ethtool -k ethX", where X is the network device number. At least
|
||||
"tx-checksumming" and "scatter-gather" should be enabled.
|
||||
|
||||
If you have in your kernel log error messages like:
|
||||
|
||||
iscsi-scst: ***ERROR*** net_priv isn't NULL and != ref_cmd
|
||||
|
||||
|
||||
@@ -689,6 +689,13 @@ retry2:
|
||||
else
|
||||
goto out_res;
|
||||
}
|
||||
#ifdef NET_PAGE_CALLBACKS_DEFINED
|
||||
if (atomic_read(&ref_cmd->net_ref_cnt) == 0) {
|
||||
TRACE_DBG("%s", "sendpage() not called "
|
||||
"get_page(), zeroing net_priv");
|
||||
sg[idx].page->net_priv = NULL;
|
||||
}
|
||||
#endif
|
||||
if (res == size) {
|
||||
conn->write_size = 0;
|
||||
return saved_size;
|
||||
@@ -711,6 +718,13 @@ retry1:
|
||||
else
|
||||
goto out_res;
|
||||
}
|
||||
#ifdef NET_PAGE_CALLBACKS_DEFINED
|
||||
if (atomic_read(&ref_cmd->net_ref_cnt) == 0) {
|
||||
TRACE_DBG("%s", "sendpage() not called get_page(), "
|
||||
"zeroing net_priv");
|
||||
sg[idx].page->net_priv = NULL;
|
||||
}
|
||||
#endif
|
||||
if (res == sendsize) {
|
||||
idx++;
|
||||
offset = 0;
|
||||
|
||||
@@ -161,6 +161,7 @@ int scst_alloc_device(int gfp_mask, struct scst_device **out_dev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev->handler = &scst_null_devtype;
|
||||
dev->p_cmd_lists = &scst_main_cmd_lists;
|
||||
atomic_set(&dev->dev_cmd_count, 0);
|
||||
spin_lock_init(&dev->dev_lock);
|
||||
@@ -357,7 +358,6 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
tgt_dev->acg_dev = acg_dev;
|
||||
tgt_dev->sess = sess;
|
||||
atomic_set(&tgt_dev->tgt_dev_cmd_count, 0);
|
||||
|
||||
|
||||
scst_sgv_pool_use_norm(tgt_dev);
|
||||
|
||||
@@ -387,14 +387,14 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
}
|
||||
|
||||
if (dev->scsi_dev != NULL) {
|
||||
TRACE_DBG("host=%d, channel=%d, id=%d, lun=%d, "
|
||||
TRACE_MGMT_DBG("host=%d, channel=%d, id=%d, lun=%d, "
|
||||
"SCST lun=%Ld", dev->scsi_dev->host->host_no,
|
||||
dev->scsi_dev->channel, dev->scsi_dev->id,
|
||||
dev->scsi_dev->lun, (uint64_t)tgt_dev->lun);
|
||||
}
|
||||
else {
|
||||
TRACE_MGMT_DBG("Virtual device SCST lun=%Ld",
|
||||
(uint64_t)tgt_dev->lun);
|
||||
TRACE_MGMT_DBG("Virtual device %s on SCST lun=%Ld",
|
||||
dev->virt_name, (uint64_t)tgt_dev->lun);
|
||||
}
|
||||
|
||||
spin_lock_init(&tgt_dev->tgt_dev_lock);
|
||||
|
||||
@@ -101,7 +101,6 @@ struct scst_cmd_lists scst_main_cmd_lists;
|
||||
|
||||
struct scst_tasklet scst_tasklets[NR_CPUS];
|
||||
|
||||
|
||||
spinlock_t scst_mcmd_lock = SPIN_LOCK_UNLOCKED;
|
||||
LIST_HEAD(scst_active_mgmt_cmd_list);
|
||||
LIST_HEAD(scst_delayed_mgmt_cmd_list);
|
||||
@@ -138,6 +137,11 @@ module_param_named(scst_max_cmd_mem, scst_max_cmd_mem, long, 0);
|
||||
MODULE_PARM_DESC(scst_max_cmd_mem, "Maximum memory allowed to be consumed by "
|
||||
"the SCST commands at any given time in Mb");
|
||||
|
||||
struct scst_dev_type scst_null_devtype =
|
||||
{
|
||||
name: "null_handler",
|
||||
};
|
||||
|
||||
int scst_register_target_template(struct scst_tgt_template *vtt)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -574,7 +578,7 @@ static void scst_unregister_device(struct scsi_device *scsidp)
|
||||
scst_acg_remove_dev(acg_dev->acg, dev);
|
||||
}
|
||||
|
||||
scst_assign_dev_handler(dev, NULL);
|
||||
scst_assign_dev_handler(dev, &scst_null_devtype);
|
||||
|
||||
put_disk(dev->rq_disk);
|
||||
scst_free_device(dev);
|
||||
@@ -718,7 +722,7 @@ void scst_unregister_virtual_device(int id)
|
||||
scst_acg_remove_dev(acg_dev->acg, dev);
|
||||
}
|
||||
|
||||
scst_assign_dev_handler(dev, NULL);
|
||||
scst_assign_dev_handler(dev, &scst_null_devtype);
|
||||
|
||||
PRINT_INFO_PR("Detached SCSI target mid-level from virtual device %s "
|
||||
"(id %d)", dev->virt_name, dev->virt_id);
|
||||
@@ -744,7 +748,7 @@ int scst_register_dev_driver(struct scst_dev_type *dev_type)
|
||||
|
||||
res = scst_dev_handler_check(dev_type);
|
||||
if (res != 0)
|
||||
goto out_err;
|
||||
goto out_error;
|
||||
|
||||
#if !defined(SCSI_EXEC_REQ_FIFO_DEFINED) && !defined(STRICT_SERIALIZING)
|
||||
if (dev_type->exec == NULL) {
|
||||
@@ -753,14 +757,14 @@ int scst_register_dev_driver(struct scst_dev_type *dev_type)
|
||||
"scst_exec_req_fifo-<kernel-version>.patch or define "
|
||||
"STRICT_SERIALIZING", dev_type->name);
|
||||
res = -EINVAL;
|
||||
goto out_err;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
scst_suspend_activity();
|
||||
if (mutex_lock_interruptible(&scst_mutex) != 0) {
|
||||
res = -EINTR;
|
||||
goto out_err;
|
||||
goto out_err_res;
|
||||
}
|
||||
|
||||
exist = 0;
|
||||
@@ -783,7 +787,7 @@ int scst_register_dev_driver(struct scst_dev_type *dev_type)
|
||||
list_add_tail(&dev_type->dev_type_list_entry, &scst_dev_type_list);
|
||||
|
||||
list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
|
||||
if ((dev->scsi_dev == NULL) || (dev->handler != NULL))
|
||||
if ((dev->scsi_dev == NULL) || (dev->handler != &scst_null_devtype))
|
||||
continue;
|
||||
if (dev->scsi_dev->type == dev_type->type)
|
||||
scst_assign_dev_handler(dev, dev_type);
|
||||
@@ -804,8 +808,10 @@ out:
|
||||
out_up:
|
||||
mutex_unlock(&scst_mutex);
|
||||
|
||||
out_err:
|
||||
out_err_res:
|
||||
scst_resume_activity();
|
||||
|
||||
out_error:
|
||||
PRINT_ERROR_PR("Failed to register device handler \"%s\" for type %d",
|
||||
dev_type->name, dev_type->type);
|
||||
goto out;
|
||||
@@ -836,7 +842,7 @@ void scst_unregister_dev_driver(struct scst_dev_type *dev_type)
|
||||
|
||||
list_for_each_entry(dev, &scst_dev_list, dev_list_entry) {
|
||||
if (dev->handler == dev_type) {
|
||||
scst_assign_dev_handler(dev, NULL);
|
||||
scst_assign_dev_handler(dev, &scst_null_devtype);
|
||||
TRACE_DBG("Dev handler removed from device %p", dev);
|
||||
}
|
||||
}
|
||||
@@ -1035,6 +1041,8 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
LIST_HEAD(attached_tgt_devs);
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
sBUG_ON(handler == NULL);
|
||||
|
||||
if (dev->handler == handler)
|
||||
goto out;
|
||||
@@ -1099,7 +1107,7 @@ out_thr_null:
|
||||
|
||||
out_null:
|
||||
if (res != 0)
|
||||
dev->handler = NULL;
|
||||
dev->handler = &scst_null_devtype;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
|
||||
@@ -212,6 +212,8 @@ extern void __scst_del_cmd_threads(int num);
|
||||
extern spinlock_t scst_temp_UA_lock;
|
||||
extern uint8_t scst_temp_UA[SCST_SENSE_BUFFERSIZE];
|
||||
|
||||
extern struct scst_dev_type scst_null_devtype;
|
||||
|
||||
extern struct scst_cmd *__scst_check_deferred_commands(
|
||||
struct scst_tgt_dev *tgt_dev);
|
||||
|
||||
|
||||
@@ -2596,7 +2596,7 @@ static int scst_translate_lun(struct scst_cmd *cmd)
|
||||
if (tgt_dev->lun == cmd->lun) {
|
||||
TRACE_DBG("tgt_dev %p found", tgt_dev);
|
||||
|
||||
if (unlikely(tgt_dev->dev->handler == NULL)) {
|
||||
if (unlikely(tgt_dev->dev->handler == &scst_null_devtype)) {
|
||||
PRINT_INFO_PR("Dev handler for device "
|
||||
"%Ld is NULL, the device will not be "
|
||||
"visible remotely", (uint64_t)cmd->lun);
|
||||
|
||||
Reference in New Issue
Block a user