From: <vl...@us...> - 2007-10-18 10:12:44
|
Revision: 205 http://scst.svn.sourceforge.net/scst/?rev=205&view=rev Author: vlnb Date: 2007-10-18 03:12:34 -0700 (Thu, 18 Oct 2007) Log Message: ----------- - 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 Modified Paths: -------------- trunk/iscsi-scst/README trunk/iscsi-scst/kernel/nthread.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2007-10-02 15:04:04 UTC (rev 204) +++ trunk/iscsi-scst/README 2007-10-18 10:12:34 UTC (rev 205) @@ -52,8 +52,16 @@ 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 with the corresponding kernel BUG dump, then put_page_callback patch you Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2007-10-02 15:04:04 UTC (rev 204) +++ trunk/iscsi-scst/kernel/nthread.c 2007-10-18 10:12:34 UTC (rev 205) @@ -689,6 +689,13 @@ 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 @@ 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; Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-10-02 15:04:04 UTC (rev 204) +++ trunk/scst/src/scst_lib.c 2007-10-18 10:12:34 UTC (rev 205) @@ -161,6 +161,7 @@ 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 @@ 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 @@ } 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); Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2007-10-02 15:04:04 UTC (rev 204) +++ trunk/scst/src/scst_main.c 2007-10-18 10:12:34 UTC (rev 205) @@ -101,7 +101,6 @@ 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_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 @@ 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 @@ 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 @@ 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 @@ "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 @@ 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_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 @@ 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 @@ LIST_HEAD(attached_tgt_devs); TRACE_ENTRY(); + + sBUG_ON(handler == NULL); if (dev->handler == handler) goto out; @@ -1099,7 +1107,7 @@ out_null: if (res != 0) - dev->handler = NULL; + dev->handler = &scst_null_devtype; out: TRACE_EXIT_RES(res); Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2007-10-02 15:04:04 UTC (rev 204) +++ trunk/scst/src/scst_priv.h 2007-10-18 10:12:34 UTC (rev 205) @@ -212,6 +212,8 @@ 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); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-10-02 15:04:04 UTC (rev 204) +++ trunk/scst/src/scst_targ.c 2007-10-18 10:12:34 UTC (rev 205) @@ -2596,7 +2596,7 @@ 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); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |