diff --git a/iscsi-scst/README b/iscsi-scst/README index d80e33f08..ad1ff5bdc 100644 --- a/iscsi-scst/README +++ b/iscsi-scst/README @@ -332,8 +332,13 @@ Each target subdirectory contains the following entries: - tid - TID of this target. -Subdirectory "sessions" contains one subdirectory for each connected -session with name equal to name of the connected initiator. +The "sessions" subdirectory contains the following attribute: + + - thread_pid - the process identifiers (PIDs) of the iscsird and iscsiwr + threads that process SCSI commands associated with this session. + +Additionally, the "sessions" subdirectory contains one subdirectory for each +connected session with name equal to name of the connected initiator. Each session subdirectory contains the following entries: diff --git a/iscsi-scst/kernel/digest.c b/iscsi-scst/kernel/digest.c index f6ed94418..e9c7c7787 100644 --- a/iscsi-scst/kernel/digest.c +++ b/iscsi-scst/kernel/digest.c @@ -205,8 +205,7 @@ int digest_rx_data(struct iscsi_cmnd *cmnd) cmnd->conn->rpadding); if (unlikely(crc != cmnd->ddigest)) { - TRACE(TRACE_MINOR|TRACE_MGMT_DEBUG, "%s", "RX data digest " - "failed"); + PRINT_ERROR("RX data digest failed, stable pages disabled?"); TRACE_MGMT_DBG("Calculated crc %x, ddigest %x, offset %d", crc, cmnd->ddigest, offset); iscsi_dump_pdu(&cmnd->pdu); diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index b3ab3f72c..7e13fffbd 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -4110,11 +4110,13 @@ static void __iscsi_threads_pool_put(struct iscsi_thread_pool *p) TRACE_DBG("Freeing iSCSI thread pool %p", p); + mutex_lock(&p->tp_mutex); list_for_each_entry_safe(t, tt, &p->threads_list, threads_list_entry) { kthread_stop(t->thr); list_del(&t->threads_list_entry); kfree(t); } + mutex_unlock(&p->tp_mutex); list_del(&p->thread_pools_list_entry); @@ -4190,6 +4192,7 @@ int iscsi_threads_pool_get(const cpumask_t *cpu_mask, else cpumask_copy(&p->cpu_mask, cpu_mask); p->thread_pool_ref = 1; + mutex_init(&p->tp_mutex); INIT_LIST_HEAD(&p->threads_list); if (cpu_mask == NULL) @@ -4221,7 +4224,10 @@ int iscsi_threads_pool_get(const cpumask_t *cpu_mask, kfree(t); goto out_free; } + + mutex_lock(&p->tp_mutex); list_add_tail(&t->threads_list_entry, &p->threads_list); + mutex_unlock(&p->tp_mutex); } } diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index 3e3c8f18c..50bbdee44 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -89,9 +89,11 @@ struct iscsi_thread_pool { int thread_pool_ref; - struct list_head threads_list; - + /* Entry in iscsi_thread_pools_list */ struct list_head thread_pools_list_entry; + + struct mutex tp_mutex; + struct list_head threads_list; /* protected by tp_mutex */ }; diff --git a/iscsi-scst/kernel/session.c b/iscsi-scst/kernel/session.c index 9e80c2f46..e75fc8618 100644 --- a/iscsi-scst/kernel/session.c +++ b/iscsi-scst/kernel/session.c @@ -560,6 +560,37 @@ static ssize_t iscsi_sess_reinstating_show(struct kobject *kobj, static struct kobj_attribute iscsi_sess_attr_reinstating = __ATTR(reinstating, S_IRUGO, iscsi_sess_reinstating_show, NULL); +static ssize_t iscsi_sess_thread_pid_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct scst_session *scst_sess = container_of(kobj, struct scst_session, + sess_kobj); + struct iscsi_session *sess = scst_sess_get_tgt_priv(scst_sess); + struct iscsi_thread_pool *thr_pool = sess->sess_thr_pool; + struct iscsi_thread *t; + int res = -ENOENT; + + if (!thr_pool) + goto out; + + res = 0; + + mutex_lock(&thr_pool->tp_mutex); + list_for_each_entry(t, &thr_pool->threads_list, threads_list_entry) + res += scnprintf(buf + res, PAGE_SIZE - res, "%d%s", + task_pid_vnr(t->thr), + list_is_last(&t->threads_list_entry, + &thr_pool->threads_list) ? + "\n" : " "); + mutex_unlock(&thr_pool->tp_mutex); + +out: + return res; +} + +static struct kobj_attribute iscsi_sess_thread_pid = + __ATTR(thread_pid, S_IRUGO, iscsi_sess_thread_pid_show, NULL); + const struct attribute *iscsi_sess_attrs[] = { &iscsi_sess_attr_initial_r2t.attr, &iscsi_sess_attr_immediate_data.attr, @@ -572,6 +603,7 @@ const struct attribute *iscsi_sess_attrs[] = { &iscsi_sess_attr_data_digest.attr, &iscsi_attr_sess_sid.attr, &iscsi_sess_attr_reinstating.attr, + &iscsi_sess_thread_pid.attr, NULL, }; diff --git a/nightly/conf/nightly.conf b/nightly/conf/nightly.conf index de74deda5..b13e569f3 100644 --- a/nightly/conf/nightly.conf +++ b/nightly/conf/nightly.conf @@ -3,13 +3,13 @@ ABT_DETAILS="x86_64" ABT_JOBS=5 ABT_KERNELS=" \ -3.16.3 \ +3.16.7 \ 3.15.10-nc \ -3.14.19-nc \ +3.14.23-nc \ 3.13.11-nc \ -3.12.28-nc \ +3.12.31-nc \ 3.11.10-nc \ -3.10.55-nc \ +3.10.59-nc \ 3.9.11-nc \ 3.8.13-nc \ 3.7.10-nc \ diff --git a/scst/README b/scst/README index f2755bd19..c2d6555c5 100644 --- a/scst/README +++ b/scst/README @@ -690,6 +690,16 @@ Each session subdirectory contains the following entries: See below description of the VDISK's sysfs interface for samples. +Each sessions//lun subdirectory contains the following entries: + + - active_commands - contains number of active, i.e. not yet or being + executed, SCSI commands for lun in session . + + - thread_pid - contains a single line with all the process identifiers + (PIDs) of the kernel threads that process SCSI commands intended for + lun in session . + + Access and devices visibility management (LUN masking) ------------------------------------------------------ diff --git a/scst/README_in-tree b/scst/README_in-tree index 658abb10b..67210ed60 100644 --- a/scst/README_in-tree +++ b/scst/README_in-tree @@ -552,6 +552,16 @@ Each session subdirectory contains the following entries: See below description of the VDISK's sysfs interface for samples. +Each sessions//lun subdirectory contains the following entries: + + - active_commands - contains number of active, i.e. not yet or being + executed, SCSI commands for lun in session . + + - thread_pid - contains a single line with all the process identifiers + (PIDs) of the kernel threads that process SCSI commands intended for + lun in session . + + Access and devices visibility management (LUN masking) ------------------------------------------------------ diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 64fa92490..3e45ec1b2 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -4351,7 +4351,7 @@ static enum compl_status_e vdisk_exec_mode_select(struct vdisk_cmd_params *p) int32_t length; uint8_t *address; struct scst_vdisk_dev *virt_dev; - int mselect_6, offset, type; + int mselect_6, offset, bdl, type; TRACE_ENTRY(); @@ -4370,14 +4370,17 @@ static enum compl_status_e vdisk_exec_mode_select(struct vdisk_cmd_params *p) goto out_put; } - if (mselect_6) + if (mselect_6) { + bdl = address[3]; offset = 4; - else + } else { + bdl = get_unaligned_be16(&address[6]); offset = 8; + } - if (address[offset - 1] == 8) { + if (bdl == 8) offset += 8; - } else if (address[offset - 1] != 0) { + else if (bdl != 0) { PRINT_ERROR("%s", "MODE SELECT: Wrong parameters list length"); scst_set_invalid_field_in_parm_list(cmd, offset-1, 0); goto out_put; @@ -5021,7 +5024,7 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) mm_segment_t old_fs; loff_t err = 0; ssize_t length, full_len; - uint8_t __user *address; + uint8_t *address; struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; struct file *fd = virt_dev->fd; struct iovec *iv, *eiv; @@ -5039,7 +5042,7 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) if (iv == NULL) goto out_nomem; - length = scst_get_buf_first(cmd, (uint8_t __force **)&address); + length = scst_get_buf_first(cmd, &address); if (unlikely(length < 0)) { PRINT_ERROR("scst_get_buf_first() failed: %zd", length); scst_set_cmd_error(cmd, @@ -5058,12 +5061,11 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p) full_len += length; i++; iv_count++; - iv[i].iov_base = address; + iv[i].iov_base = (uint8_t __force __user *)address; iv[i].iov_len = length; if (iv_count == UIO_MAXIOV) break; - length = scst_get_buf_next(cmd, - (uint8_t __force **)&address); + length = scst_get_buf_next(cmd, &address); } if (length == 0) { finished = true; @@ -5116,8 +5118,7 @@ restart: eiv++; eiv_count--; } else { - eiv->iov_base = - (uint8_t __force __user *)eiv->iov_base + err; + eiv->iov_base += err; eiv->iov_len -= err; break; } @@ -5131,7 +5132,7 @@ restart: if (finished) break; - length = scst_get_buf_next(cmd, (uint8_t __force **)&address); + length = scst_get_buf_next(cmd, &address); } set_fs(old_fs); diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index 64bfd19ed..ac28b01b5 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -3506,6 +3506,31 @@ static struct kobj_attribute tgt_dev_latency_attr = #endif /* CONFIG_SCST_MEASURE_LATENCY */ +static ssize_t scst_tgt_dev_thread_pid_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buffer) +{ + struct scst_tgt_dev *tgt_dev = + container_of(kobj, struct scst_tgt_dev, tgt_dev_kobj); + struct scst_cmd_threads *cmd_threads = tgt_dev->active_cmd_threads; + struct scst_cmd_thread_t *t; + int res = 0; + + spin_lock(&cmd_threads->thr_lock); + list_for_each_entry(t, &cmd_threads->threads_list, thread_list_entry) + res += scnprintf(buffer + res, PAGE_SIZE - res, "%d%s", + task_pid_vnr(t->cmd_thread), + list_is_last(&t->thread_list_entry, + &cmd_threads->threads_list) ? + "\n" : " "); + spin_unlock(&cmd_threads->thr_lock); + + return res; +} + +static struct kobj_attribute tgt_dev_thread_pid_attr = + __ATTR(thread_pid, S_IRUGO, scst_tgt_dev_thread_pid_show, NULL); + static ssize_t scst_tgt_dev_active_commands_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -3524,6 +3549,7 @@ static struct kobj_attribute tgt_dev_active_commands_attr = scst_tgt_dev_active_commands_show, NULL); static struct attribute *scst_tgt_dev_attrs[] = { + &tgt_dev_thread_pid_attr.attr, &tgt_dev_active_commands_attr.attr, #ifdef CONFIG_SCST_MEASURE_LATENCY &tgt_dev_latency_attr.attr, diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 498f27db9..eda3226b8 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -1850,8 +1850,8 @@ static int scst_report_luns_local(struct scst_cmd *cmd) cmd->driver_status = 0; if ((cmd->cdb[2] != 0) && (cmd->cdb[2] != 2)) { - PRINT_ERROR("Unsupported SELECT REPORT value %x in REPORT " - "LUNS command", cmd->cdb[2]); + TRACE(TRACE_MINOR, "Unsupported SELECT REPORT value %x in " + "REPORT LUNS command", cmd->cdb[2]); scst_set_invalid_field_in_cdb(cmd, 2, 0); goto out_compl; } diff --git a/www/target_iser.html b/www/target_iser.html index 8cb848f44..fd29367e8 100644 --- a/www/target_iser.html +++ b/www/target_iser.html @@ -1,12 +1,12 @@ - + -iSCSI Target Driver +iSER Target Driver @@ -59,10 +59,15 @@

iSCSI Extensions for RDMA (iSER) driver for iSCSI-SCST

ISER extension for ISCSI-SCST has been developed by Yan Burman and Mellanox Technologies (thank you!).

-

Current version is 3.0.0. You can find the latest development version in the SCST SVN. See the download page how to setup +

Current version is 3.0.0. You can find the latest development version in the SCST SVN in iser branch. See the download page how to setup access to it.

+ +

3.0.x-iser branch in the SCST SVN is the stable post-3.0 release iSER + branch with the latest stable fixes in the iSER driver as well as other SCST components merged from the 3.0.0 branch.

+