Merged revisions 6883,6885,6889,6892 via svnmerge from

svn+ssh://svn.code.sf.net/p/scst/svn/trunk

........
  r6883 | vlnb | 2016-05-03 19:43:06 -0700 (Tue, 03 May 2016) | 48 lines
  
  When trying to remove a megaraid_sas device, the scst will hang inside
  scst_free_device:
  
  [  380.448608] [4]: scst: Detached from scsi0, channel 2, id 1, lun 0, type 0
  [  601.138688] INFO: task kworker/0:0:4 blocked for more than 120 seconds.
  [  601.138756]       Tainted: P           OE  3.19.0-58-quantastor #64~14.04.1
  [  601.138810] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
  [  601.138869] kworker/0:0     D ffff88085c6fba58     0     4      2 0x00000000
  [  601.138926] Workqueue: events megasas_aen_polling [megaraid_sas]
  [  601.138930]  ffff88085c6fba58 ffff88085c6f09d0 0000000000013e80 ffff88085c6fbfd8
  [  601.138934]  0000000000013e80 ffffffff81c1d4e0 ffff88085c6f09d0 ffff88085c6fba38
  [  601.138938]  ffff88085c6fbbd8 7fffffffffffffff ffff88085c6fbbd0 ffff88085c6f09d0
  [  601.138942] Call Trace:
  [  601.138955]  [<ffffffff817b5469>] schedule+0x29/0x70
  [  601.138960]  [<ffffffff817b8574>] schedule_timeout+0x244/0x2c0
  [  601.138968]  [<ffffffff8115fbcb>] ? irq_work_queue+0x6b/0x90
  [  601.138975]  [<ffffffff810cb8e2>] ? wake_up_klogd+0x32/0x40
  [  601.138979]  [<ffffffff810cbaf8>] ? console_unlock+0x208/0x480
  [  601.138983]  [<ffffffff817b61c4>] wait_for_completion+0xa4/0x170
  [  601.138989]  [<ffffffff810a1ea0>] ? wake_up_state+0x20/0x20
  [  601.138995]  [<ffffffff8108d94c>] flush_workqueue+0x10c/0x5b0
  [  601.139002]  [<ffffffff8108de05>] flush_scheduled_work+0x15/0x20
  [  601.139044]  [<ffffffffc09314f6>] scst_free_device+0x16/0x50 [scst]
  [  601.139051]  [<ffffffffc091a86f>] scst_remove+0x2df/0x3a0 [scst]
  [  601.139056]  [<ffffffffc028c093>] ? enclosure_find+0x93/0xa0 [enclosure]
  [  601.139061]  [<ffffffff814f3971>] device_del+0xe1/0x270
  [  601.139062]  [<ffffffff814f3b22>] device_unregister+0x22/0x70
  [  601.139066]  [<ffffffff815549ab>] __scsi_remove_device+0xbb/0xd0
  [  601.139068]  [<ffffffff815549e6>] scsi_remove_device+0x26/0x40
  [  601.139074]  [<ffffffffc039fb22>] megasas_aen_polling+0x362/0x610 [megaraid_sas]
  [  601.139076]  [<ffffffff8108eeaf>] process_one_work+0x14f/0x440
  [  601.139077]  [<ffffffff8108fab8>] worker_thread+0x118/0x510
  [  601.139079]  [<ffffffff8108f9a0>] ? rescuer_thread+0x3d0/0x3d0
  [  601.139082]  [<ffffffff81094b49>] kthread+0xc9/0xe0
  [  601.139084]  [<ffffffff81094a80>] ? kthread_create_on_node+0x1c0/0x1c0
  [  601.139087]  [<ffffffff817b9798>] ret_from_fork+0x58/0x90
  [  601.139089]  [<ffffffff81094a80>] ? kthread_create_on_node+0x1c0/0x1c0
  
  The problem is that scst_free_device will call flush_scheduled_work to wait
  for ext_blockers_work, but scst_free_device itself is called from
  schedule_work, thus creating deadlock.
  
  Instead of using heavy-handed flush_scheduled_work, we use flush_work to wait
  for ext_blockers_work to finish.
  
  Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
........
  r6885 | vlnb | 2016-05-04 18:53:17 -0700 (Wed, 04 May 2016) | 3 lines
  
  Make copy manager update internal data on INQUIRY changing vdisk events
........
  r6889 | vlnb | 2016-05-06 17:47:57 -0700 (Fri, 06 May 2016) | 3 lines
  
  qla2x00t: clarify that NPIV is not supported in this version
........
  r6892 | vlnb | 2016-05-26 18:02:11 -0700 (Thu, 26 May 2016) | 6 lines
  
  scst: update README how to configure SCST, so VMware start using EXTENDED COPY between datastores
  
  Based on information from Artur Piechocki <artur.piechocki@open-e.com>
  Tested-By: Isaac Goldbaum <isaac.goldbaum@mail.ru>
........


git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/3.1.x@6894 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2016-05-27 02:40:43 +00:00
parent b737e3e036
commit 2a236649c1
8 changed files with 206 additions and 3 deletions
+5
View File
@@ -185,6 +185,11 @@ default.
N_Port ID Virtualization
------------------------
Unfortunately, due to severe problems in the original qla2xxx driver,
NPIV in this version is not supported. If you need NPIV, you can use
previous version 2.1 of this driver.
N_Port ID Virtualization (NPIV) is a Fibre Channel facility allowing
multiple N_Port IDs to share a single physical N_Port. NPIV is fully
supported by this driver. You must have 24xx+ ISPs with NPIV-supporting
+28
View File
@@ -1810,6 +1810,34 @@ benefit from SCST VAAI implementation. Those actions described in the
implementation notes below. For vdisk and fileio_tgt handlers they have
already been implemented.
IMPORTANT: To use EXTENDED COPY command between LUNs (datastores) they all
========= MUST have the same PRODUCT IDENTIFICATION INQUIRY field. By
default, to simplify remote devices identification, SCST uses
vdisk names as PRODUCT IDENTIFICATION, so SCST devices look
differently from the initiators. However, for some reasons,
VMware does not use EXTENDED COPY between LUNs with different
PRODUCT IDENTIFICATION. Thus, to be able to use full VAAI in
your VMware setups you must manually set PRODUCT
IDENTIFICATION for all your VMware LUNs to the same value,
for instance, "SCST", via using "prod_id" attribute. It could
be done either by adding "prod_id" attribute to scstadmin
scst.conf, or by directly writing to SCST sysfs attribute.
For example:
HANDLER vdisk_blockio {
DEVICE blockio1 {
filename /dev/sda5
prod_id SCST
}
or
echo SCST >/sys/kernel/scst_tgt/devices/blockio1/prod_id
correspondingly.
Note, this prod_id modification must be done on all
datastores BEFORE VMware connects to them.
Implementation notes
....................
+28
View File
@@ -1663,6 +1663,34 @@ benefit from SCST VAAI implementation. Those actions described in the
implementation notes below. For vdisk and fileio_tgt handlers they have
already been implemented.
IMPORTANT: To use EXTENDED COPY command between LUNs (datastores) they all
========= MUST have the same PRODUCT IDENTIFICATION INQUIRY field. By
default, to simplify remote devices identification, SCST uses
vdisk names as PRODUCT IDENTIFICATION, so SCST devices look
differently from the initiators. However, for some reasons,
VMware does not use EXTENDED COPY between LUNs with different
PRODUCT IDENTIFICATION. Thus, to be able to use full VAAI in
your VMware setups you must manually set PRODUCT
IDENTIFICATION for all your VMware LUNs to the same value,
for instance, "SCST", via using "prod_id" attribute. It could
be done either by adding "prod_id" attribute to scstadmin
scst.conf, or by directly writing to SCST sysfs attribute.
For example:
HANDLER vdisk_blockio {
DEVICE blockio1 {
filename /dev/sda5
prod_id SCST
}
or
echo SCST >/sys/kernel/scst_tgt/devices/blockio1/prod_id
correspondingly.
Note, this prod_id modification must be done on all
datastores BEFORE VMware connects to them.
Implementation notes
....................
+2
View File
@@ -5424,6 +5424,8 @@ void scst_reassign_retained_sess_states(struct scst_session *new_sess,
int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun);
void scst_dev_inquiry_data_changed(struct scst_device *dev);
/*
* Has to be put here open coded, because Linux doesn't have equivalent, which
* allows exclusive wake ups of threads in LIFO order. We need it to let (yet)
+48 -1
View File
@@ -233,6 +233,8 @@ struct scst_vdisk_dev {
char *dif_filename;
struct work_struct vdev_inq_changed_work;
/* Only to pass it to attach() callback. Don't use them anywhere else! */
int blk_shift;
enum scst_dif_mode dif_mode;
@@ -652,7 +654,10 @@ static const struct attribute *vcdrom_attrs[] = {
#endif /* CONFIG_SCST_PROC */
/* Protects vdisks addition/deletion and related activities, like search */
/*
* Protects vdisks addition/deletion and related activities, like search.
* Outer mutex regarding scst_mutex.
*/
static DEFINE_MUTEX(scst_vdisk_mutex);
/*
@@ -7654,6 +7659,23 @@ static void vdisk_free_bioset(struct scst_vdisk_dev *virt_dev)
}
#endif
static void vdev_inq_changed_fn(struct work_struct *work)
{
struct scst_vdisk_dev *virt_dev = container_of(work,
struct scst_vdisk_dev, vdev_inq_changed_work);
struct scst_device *dev = virt_dev->dev;
TRACE_ENTRY();
TRACE_DBG("Updating INQUIRY data for virt_dev %p (dev %s)",
virt_dev, dev->virt_name);
scst_dev_inquiry_data_changed(dev);
TRACE_EXIT();
return;
}
/* scst_vdisk_mutex supposed to be held */
static int vdev_create(struct scst_dev_type *devt,
const char *name, struct scst_vdisk_dev **res_virt_dev)
@@ -7687,6 +7709,7 @@ static int vdev_create(struct scst_dev_type *devt,
virt_dev->thin_provisioned = DEF_THIN_PROVISIONED;
virt_dev->tst = DEF_TST;
virt_dev->expl_alua = DEF_EXPL_ALUA;
INIT_WORK(&virt_dev->vdev_inq_changed_work, vdev_inq_changed_fn);
virt_dev->blk_shift = DEF_DISK_BLOCK_SHIFT;
@@ -7748,6 +7771,8 @@ out_free:
static void vdev_destroy(struct scst_vdisk_dev *virt_dev)
{
cancel_work_sync(&virt_dev->vdev_inq_changed_work);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
vdisk_free_bioset(virt_dev);
#endif
@@ -9287,6 +9312,8 @@ static ssize_t vdev_sysfs_t10_vend_id_store(struct kobject *kobj,
virt_dev->t10_vend_id_set = 1;
write_unlock(&vdisk_serial_rwlock);
schedule_work(&virt_dev->vdev_inq_changed_work);
res = count;
out:
@@ -9346,6 +9373,8 @@ static ssize_t vdev_sysfs_vend_specific_id_store(struct kobject *kobj,
virt_dev->vend_specific_id_set = 1;
write_unlock(&vdisk_serial_rwlock);
schedule_work(&virt_dev->vdev_inq_changed_work);
res = count;
out:
@@ -9404,6 +9433,8 @@ static ssize_t vdev_sysfs_prod_id_store(struct kobject *kobj,
virt_dev->prod_id_set = 1;
write_unlock(&vdisk_serial_rwlock);
schedule_work(&virt_dev->vdev_inq_changed_work);
res = count;
out:
@@ -9462,6 +9493,8 @@ static ssize_t vdev_sysfs_prod_rev_lvl_store(struct kobject *kobj,
virt_dev->prod_rev_lvl_set = 1;
write_unlock(&vdisk_serial_rwlock);
schedule_work(&virt_dev->vdev_inq_changed_work);
res = count;
out:
@@ -9523,6 +9556,8 @@ static ssize_t vdev_sysfs_scsi_device_name_store(struct kobject *kobj,
virt_dev->scsi_device_name_set = 0;
write_unlock(&vdisk_serial_rwlock);
schedule_work(&virt_dev->vdev_inq_changed_work);
res = count;
out:
@@ -9593,6 +9628,8 @@ static ssize_t vdev_sysfs_t10_dev_id_store(struct kobject *kobj,
virt_dev->t10_dev_id_set = 1;
schedule_work(&virt_dev->vdev_inq_changed_work);
res = count;
PRINT_INFO("T10 device id for device %s changed to %s", virt_dev->name,
@@ -9675,6 +9712,9 @@ static ssize_t vdev_sysfs_eui64_id_store(struct kobject *kobj,
#endif
write_unlock(&vdisk_serial_rwlock);
if (res >= 0)
schedule_work(&virt_dev->vdev_inq_changed_work);
out:
return res;
}
@@ -9756,6 +9796,9 @@ static ssize_t vdev_sysfs_naa_id_store(struct kobject *kobj,
#endif
write_unlock(&vdisk_serial_rwlock);
if (res >= 0)
schedule_work(&virt_dev->vdev_inq_changed_work);
out:
return res;
}
@@ -9819,6 +9862,8 @@ static ssize_t vdev_sysfs_usn_store(struct kobject *kobj,
virt_dev->usn_set = 1;
schedule_work(&virt_dev->vdev_inq_changed_work);
res = count;
PRINT_INFO("USN for device %s changed to %s", virt_dev->name,
@@ -9873,6 +9918,8 @@ static ssize_t vdev_sysfs_inq_vend_specific_store(struct kobject *kobj,
virt_dev->inq_vend_specific_len = len;
write_unlock(&vdisk_serial_rwlock);
schedule_work(&virt_dev->vdev_inq_changed_work);
res = count;
out:
+68 -1
View File
@@ -2518,6 +2518,36 @@ static bool scst_cm_is_lun_free(unsigned int lun)
return res;
}
/* scst_mutex supposed to be held and activities suspended */
static unsigned int scst_cm_get_lun(const struct scst_device *dev)
{
unsigned int res = -1;
int i;
bool found = false;
TRACE_ENTRY();
for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
struct list_head *head = &scst_cm_sess->sess_tgt_dev_list[i];
struct scst_tgt_dev *tgt_dev;
list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
if (tgt_dev->dev == dev) {
res = tgt_dev->lun;
found = true;
TRACE_DBG("LUN %d found (full LUN %lld)",
res, tgt_dev->lun);
goto out;
}
}
}
sBUG_ON(!found);
out:
TRACE_EXIT_RES(res);
return res;
}
/* scst_mutex supposed to be held and activities suspended */
static int scst_cm_dev_register(struct scst_device *dev, uint64_t lun)
{
@@ -2583,6 +2613,7 @@ out_unblock:
spin_lock_bh(&dev->dev_lock);
scst_unblock_dev(dev);
spin_unlock_bh(&dev->dev_lock);
scst_acg_del_lun(scst_cm_tgt->default_acg, lun, false);
out_err:
@@ -2629,6 +2660,41 @@ out:
return;
}
void scst_cm_update_dev(struct scst_device *dev)
{
int rc;
TRACE_ENTRY();
TRACE_MGMT_DBG("copy manager: updating device %s", dev->virt_name);
scst_suspend_activity(SCST_SUSPEND_TIMEOUT_UNLIMITED);
mutex_lock(&scst_mutex);
scst_cm_dev_unregister(dev, false);
spin_lock_bh(&dev->dev_lock);
scst_block_dev(dev);
spin_unlock_bh(&dev->dev_lock);
rc = scst_cm_send_init_inquiry(dev, scst_cm_get_lun(dev), NULL);
if (rc != 0)
goto out_unblock;
out_resume:
mutex_unlock(&scst_mutex);
scst_resume_activity();
TRACE_EXIT();
return;
out_unblock:
spin_lock_bh(&dev->dev_lock);
scst_unblock_dev(dev);
spin_unlock_bh(&dev->dev_lock);
goto out_resume;
}
/* scst_mutex supposed to be held and activities suspended */
int scst_cm_on_dev_register(struct scst_device *dev)
{
@@ -3650,7 +3716,8 @@ static void scst_cm_task_mgmt_fn_done(struct scst_mgmt_cmd *scst_mcmd)
static int scst_cm_report_aen(struct scst_aen *aen)
{
/* Nothing to do */
return 0;
scst_aen_done(aen);
return SCST_AEN_RES_SUCCESS;
}
static struct scst_tgt_template scst_cm_tgtt = {
+25 -1
View File
@@ -2855,6 +2855,30 @@ void scst_requeue_ua(struct scst_cmd *cmd, const uint8_t *buf, int size)
return;
}
void scst_dev_inquiry_data_changed(struct scst_device *dev)
{
struct scst_tgt_dev *tgt_dev;
TRACE_ENTRY();
TRACE_MGMT_DBG("Updating INQUIRY data for dev %s", dev->virt_name);
mutex_lock(&scst_mutex);
list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) {
TRACE_DBG("INQUIRY DATA HAS CHANGED on tgt_dev %p", tgt_dev);
scst_gen_aen_or_ua(tgt_dev, SCST_LOAD_SENSE(scst_sense_inquiry_data_changed));
}
mutex_unlock(&scst_mutex);
scst_cm_update_dev(dev);
TRACE_EXIT();
return;
}
EXPORT_SYMBOL(scst_dev_inquiry_data_changed);
/* The activity supposed to be suspended and scst_mutex held */
static void scst_check_reassign_sess(struct scst_session *sess)
{
@@ -4206,7 +4230,7 @@ void scst_free_device(struct scst_device *dev)
#endif
/* Ensure that ext_blockers_work is done */
flush_scheduled_work();
flush_work(&dev->ext_blockers_work);
scst_deinit_threads(&dev->dev_cmd_threads);
+2
View File
@@ -857,6 +857,7 @@ static inline bool scst_lba1_inside_lba2(int64_t lba1,
#ifndef CONFIG_SCST_PROC
void scst_cm_update_dev(struct scst_device *dev);
int scst_cm_on_dev_register(struct scst_device *dev);
void scst_cm_on_dev_unregister(struct scst_device *dev);
@@ -890,6 +891,7 @@ void scst_cm_exit(void);
#else /* #ifndef CONFIG_SCST_PROC */
static inline void scst_cm_update_dev(struct scst_device *dev) {}
static inline int scst_cm_on_dev_register(struct scst_device *dev) { return 0; }
static inline void scst_cm_on_dev_unregister(struct scst_device *dev) {}