mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-14 09:11:27 +00:00
- Threads made per-device
- Minor cleanups and fixes git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@125 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
2
Makefile
2
Makefile
@@ -154,5 +154,5 @@ help:
|
||||
.PHONY: all install uninstall clean extraclean help \
|
||||
qla qla_install qla_uninstall qla_clean qla_extraclean \
|
||||
lsi lsi_install lsi_uninstall lsi_clean lsi_extraclean \
|
||||
scst scst_install scst_uninstall scst_clean scst_extraclean
|
||||
scst scst_install scst_uninstall scst_clean scst_extraclean \
|
||||
usr usr_install usr_uninstall usr_clean usr_extraclean
|
||||
|
||||
@@ -251,6 +251,7 @@ struct scst_user_sess
|
||||
{
|
||||
uint64_t sess_h;
|
||||
uint64_t lun;
|
||||
uint16_t threads_num;
|
||||
uint8_t rd_only;
|
||||
char initiator_name[SCST_MAX_NAME];
|
||||
},
|
||||
@@ -260,7 +261,10 @@ where:
|
||||
- sess_h - session's handle, may not be 0
|
||||
|
||||
- lun - assigned LUN for this device in this session
|
||||
|
||||
|
||||
- threads_num - specifies amount of additional threads, requested by
|
||||
the corresponding target driver
|
||||
|
||||
- rd_only - if true, this device is read only in this session
|
||||
|
||||
- initiator_name - name of the remote initiator, which initiated this
|
||||
|
||||
@@ -619,9 +619,6 @@ struct scst_tgt_template
|
||||
/* The pointer to the /proc directory entry */
|
||||
struct proc_dir_entry *proc_tgt_root;
|
||||
|
||||
/* Dedicated thread number */
|
||||
int thread_num;
|
||||
|
||||
/* Device number in /proc */
|
||||
int proc_dev_num;
|
||||
};
|
||||
@@ -1181,6 +1178,12 @@ struct scst_device
|
||||
{
|
||||
struct scst_dev_type *handler; /* corresponding dev handler */
|
||||
|
||||
/* Pointer to lists of commands with the lock */
|
||||
struct scst_cmd_lists *p_cmd_lists;
|
||||
|
||||
/* Lists of commands with the lock, if dedicated threads are used */
|
||||
struct scst_cmd_lists cmd_lists;
|
||||
|
||||
unsigned short type; /* SCSI type of the device */
|
||||
|
||||
/*************************************************************
|
||||
@@ -1250,6 +1253,9 @@ struct scst_device
|
||||
|
||||
/* List of acg_dev's, one per acg, protected by scst_mutex */
|
||||
struct list_head dev_acg_dev_list;
|
||||
|
||||
/* List of dedicated threads. Doesn't need any protection. */
|
||||
struct list_head threads_list;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1276,9 +1282,6 @@ struct scst_tgt_dev
|
||||
struct scst_device *dev; /* to save extra dereferences */
|
||||
lun_t lun; /* to save extra dereferences */
|
||||
|
||||
/* Pointer to lists of commands with the lock */
|
||||
struct scst_cmd_lists *p_cmd_lists;
|
||||
|
||||
/* How many cmds alive on this dev in this session */
|
||||
atomic_t cmd_count;
|
||||
|
||||
@@ -1313,9 +1316,6 @@ struct scst_tgt_dev
|
||||
atomic_t *cur_sn_slot;
|
||||
atomic_t sn_slots[10];
|
||||
|
||||
/* Lists of commands with the lock, if dedicated threads are used */
|
||||
struct scst_cmd_lists cmd_lists;
|
||||
|
||||
/* Used for storage of dev handler private stuff */
|
||||
void *dh_priv;
|
||||
|
||||
@@ -1337,8 +1337,7 @@ struct scst_tgt_dev
|
||||
/* internal tmp list entry */
|
||||
struct list_head extra_tgt_dev_list_entry;
|
||||
|
||||
/* List of dedicated threads. Doesn't need any protection. */
|
||||
struct list_head threads_list;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -57,9 +57,13 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTRACHECKS
|
||||
#define EXTRACHECKS_BUG_ON(a) sBUG_ON(a)
|
||||
#define EXTRACHECKS_BUG_ON(a) sBUG_ON(a)
|
||||
#define EXTRACHECKS_WARN_ON(a) WARN_ON(a)
|
||||
#define EXTRACHECKS_WARN_ON_ONCE(a) WARN_ON_ONCE(a)
|
||||
#else
|
||||
#define EXTRACHECKS_BUG_ON(a)
|
||||
#define EXTRACHECKS_WARN_ON(a)
|
||||
#define EXTRACHECKS_WARN_ON_ONCE(a)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -106,6 +106,7 @@ struct scst_user_sess
|
||||
{
|
||||
aligned_u64 sess_h;
|
||||
aligned_u64 lun;
|
||||
uint16_t threads_num;
|
||||
uint8_t rd_only;
|
||||
char initiator_name[SCST_MAX_NAME];
|
||||
};
|
||||
|
||||
@@ -2148,6 +2148,8 @@ static int dev_user_attach(struct scst_device *sdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
sdev->p_cmd_lists = &dev->cmd_lists;
|
||||
|
||||
sdev->dh_priv = dev;
|
||||
|
||||
PRINT_INFO_PR("Attached user space SCSI target virtual device \"%s\"",
|
||||
@@ -2219,8 +2221,6 @@ static int dev_user_attach_tgt(struct scst_tgt_dev *tgt_dev)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
tgt_dev->p_cmd_lists = &dev->cmd_lists;
|
||||
|
||||
ucmd = dev_user_alloc_ucmd(dev, GFP_KERNEL);
|
||||
if (ucmd == NULL)
|
||||
goto out_nomem;
|
||||
@@ -2235,6 +2235,7 @@ static int dev_user_attach_tgt(struct scst_tgt_dev *tgt_dev)
|
||||
ucmd->user_cmd.subcode = SCST_USER_ATTACH_SESS;
|
||||
ucmd->user_cmd.sess.sess_h = (unsigned long)tgt_dev;
|
||||
ucmd->user_cmd.sess.lun = (uint64_t)tgt_dev->lun;
|
||||
ucmd->user_cmd.sess.threads_num = tgt_dev->sess->tgt->tgtt->threads_num;
|
||||
ucmd->user_cmd.sess.rd_only = tgt_dev->acg_dev->rd_only_flag;
|
||||
strncpy(ucmd->user_cmd.sess.initiator_name,
|
||||
tgt_dev->sess->initiator_name,
|
||||
@@ -2243,9 +2244,10 @@ static int dev_user_attach_tgt(struct scst_tgt_dev *tgt_dev)
|
||||
sizeof(ucmd->user_cmd.sess.initiator_name)-1] = '\0';
|
||||
|
||||
TRACE_MGMT_DBG("Preparing ATTACH_SESS %p (h %d, sess_h %Lx, LUN %Lx, "
|
||||
"rd_only_flag %d, initiator %s)", ucmd, ucmd->h,
|
||||
"threads_num %d, rd_only_flag %d, initiator %s)", ucmd, ucmd->h,
|
||||
ucmd->user_cmd.sess.sess_h, ucmd->user_cmd.sess.lun,
|
||||
ucmd->user_cmd.sess.rd_only, ucmd->user_cmd.sess.initiator_name);
|
||||
ucmd->user_cmd.sess.threads_num, ucmd->user_cmd.sess.rd_only,
|
||||
ucmd->user_cmd.sess.initiator_name);
|
||||
|
||||
ucmd->state = UCMD_STATE_ATTACH_SESS;
|
||||
|
||||
|
||||
180
scst/src/scst.c
180
scst/src/scst.c
@@ -156,6 +156,14 @@ int scst_register_target_template(struct scst_tgt_template *vtt)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (vtt->threads_num < 0) {
|
||||
PRINT_ERROR_PR("Wrong threads_num value %d for "
|
||||
"target \"%s\"", vtt->threads_num,
|
||||
vtt->name);
|
||||
res = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!vtt->no_proc_entry) {
|
||||
res = scst_build_proc_target_dir_entries(vtt);
|
||||
if (res < 0)
|
||||
@@ -467,11 +475,9 @@ static int scst_register_device(struct scsi_device *scsidp)
|
||||
scst_suspend_activity();
|
||||
down(&scst_mutex);
|
||||
|
||||
dev = scst_alloc_device(GFP_KERNEL);
|
||||
if (dev == NULL) {
|
||||
res = -ENOMEM;
|
||||
res = scst_alloc_device(GFP_KERNEL, &dev);
|
||||
if (res != 0)
|
||||
goto out_up;
|
||||
}
|
||||
|
||||
dev->type = scsidp->type;
|
||||
|
||||
@@ -618,22 +624,19 @@ int scst_register_virtual_device(struct scst_dev_type *dev_handler,
|
||||
if (res != 0)
|
||||
goto out;
|
||||
|
||||
dev = scst_alloc_device(GFP_KERNEL);
|
||||
if (dev == NULL) {
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
scst_suspend_activity();
|
||||
if (down_interruptible(&scst_mutex) != 0) {
|
||||
res = -EINTR;
|
||||
goto out_resume;
|
||||
}
|
||||
|
||||
res = scst_alloc_device(GFP_KERNEL, &dev);
|
||||
if (res != 0)
|
||||
goto out_up;
|
||||
|
||||
dev->type = dev_handler->type;
|
||||
dev->scsi_dev = NULL;
|
||||
dev->virt_name = dev_name;
|
||||
|
||||
scst_suspend_activity();
|
||||
if (down_interruptible(&scst_mutex) != 0) {
|
||||
res = -EINTR;
|
||||
goto out_free_dev;
|
||||
}
|
||||
|
||||
dev->virt_id = scst_virt_dev_last_id++;
|
||||
|
||||
list_add_tail(&dev->dev_list_entry, &scst_dev_list);
|
||||
@@ -645,7 +648,8 @@ int scst_register_virtual_device(struct scst_dev_type *dev_handler,
|
||||
res = rc;
|
||||
goto out_free_del;
|
||||
}
|
||||
|
||||
|
||||
out_up:
|
||||
up(&scst_mutex);
|
||||
|
||||
out_resume:
|
||||
@@ -666,11 +670,8 @@ out:
|
||||
|
||||
out_free_del:
|
||||
list_del(&dev->dev_list_entry);
|
||||
up(&scst_mutex);
|
||||
|
||||
out_free_dev:
|
||||
scst_free_device(dev);
|
||||
goto out_resume;
|
||||
goto out_up;
|
||||
}
|
||||
|
||||
void scst_unregister_virtual_device(int id)
|
||||
@@ -893,6 +894,123 @@ void scst_unregister_virtual_dev_driver(struct scst_dev_type *dev_type)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Called under scst_mutex and suspended activity */
|
||||
int scst_add_dev_threads(struct scst_device *dev, int num)
|
||||
{
|
||||
int i, res = 0;
|
||||
static atomic_t major = ATOMIC_INIT(0);
|
||||
int N, n = 0;
|
||||
char nm[12];
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
N = atomic_inc_return(&major);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
struct scst_cmd_thread_t *thr;
|
||||
|
||||
thr = kmalloc(sizeof(*thr), GFP_KERNEL);
|
||||
if (!thr) {
|
||||
res = -ENOMEM;
|
||||
PRINT_ERROR_PR("Failed to allocate thr %d", res);
|
||||
goto out;
|
||||
}
|
||||
strncpy(nm, dev->handler->name, ARRAY_SIZE(nm)-1);
|
||||
nm[ARRAY_SIZE(nm)-1] = '\0';
|
||||
thr->cmd_thread = kthread_run(scst_cmd_thread,
|
||||
&dev->cmd_lists, "%sd%d_%d", nm, N, n++);
|
||||
if (IS_ERR(thr->cmd_thread)) {
|
||||
res = PTR_ERR(thr->cmd_thread);
|
||||
PRINT_ERROR_PR("kthread_create() failed: %d", res);
|
||||
kfree(thr);
|
||||
goto out;
|
||||
}
|
||||
list_add(&thr->thread_list_entry, &dev->threads_list);
|
||||
}
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Called under scst_mutex and suspended activity */
|
||||
static int scst_create_dev_threads(struct scst_device *dev)
|
||||
{
|
||||
int res = 0;
|
||||
int threads_num;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (dev->handler->threads_num <= 0)
|
||||
goto out;
|
||||
|
||||
threads_num = dev->handler->threads_num;
|
||||
|
||||
spin_lock_init(&dev->cmd_lists.cmd_list_lock);
|
||||
INIT_LIST_HEAD(&dev->cmd_lists.active_cmd_list);
|
||||
init_waitqueue_head(&dev->cmd_lists.cmd_list_waitQ);
|
||||
|
||||
res = scst_add_dev_threads(dev, threads_num);
|
||||
if (res != 0)
|
||||
goto out;
|
||||
|
||||
down(&scst_suspend_mutex);
|
||||
list_add_tail(&dev->cmd_lists.lists_list_entry,
|
||||
&scst_cmd_lists_list);
|
||||
up(&scst_suspend_mutex);
|
||||
|
||||
dev->p_cmd_lists = &dev->cmd_lists;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Called under scst_mutex and suspended activity */
|
||||
void scst_del_dev_threads(struct scst_device *dev, int num)
|
||||
{
|
||||
struct scst_cmd_thread_t *ct, *tmp;
|
||||
int i = 0;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
list_for_each_entry_safe(ct, tmp, &dev->threads_list,
|
||||
thread_list_entry) {
|
||||
int rc = kthread_stop(ct->cmd_thread);
|
||||
if (rc < 0) {
|
||||
TRACE_MGMT_DBG("kthread_stop() failed: %d", rc);
|
||||
}
|
||||
list_del(&ct->thread_list_entry);
|
||||
kfree(ct);
|
||||
if ((num >0) && (++i >= num))
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Called under scst_mutex and suspended activity */
|
||||
static void scst_stop_dev_threads(struct scst_device *dev)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (list_empty(&dev->threads_list))
|
||||
goto out;
|
||||
|
||||
scst_del_dev_threads(dev, -1);
|
||||
|
||||
if (dev->p_cmd_lists == &dev->cmd_lists) {
|
||||
down(&scst_suspend_mutex);
|
||||
list_del(&dev->cmd_lists.lists_list_entry);
|
||||
up(&scst_suspend_mutex);
|
||||
}
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/* The activity supposed to be suspended and scst_mutex held */
|
||||
int scst_assign_dev_handler(struct scst_device *dev,
|
||||
struct scst_dev_type *handler)
|
||||
@@ -908,8 +1026,7 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
|
||||
if (dev->handler && dev->handler->detach_tgt) {
|
||||
list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
|
||||
dev_tgt_dev_list_entry)
|
||||
{
|
||||
dev_tgt_dev_list_entry) {
|
||||
TRACE_DBG("Calling dev handler's detach_tgt(%p)",
|
||||
tgt_dev);
|
||||
dev->handler->detach_tgt(tgt_dev);
|
||||
@@ -923,8 +1040,16 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
TRACE_DBG("%s", "Old handler's detach() returned");
|
||||
}
|
||||
|
||||
scst_stop_dev_threads(dev);
|
||||
|
||||
dev->handler = handler;
|
||||
|
||||
if (handler) {
|
||||
res = scst_create_dev_threads(dev);
|
||||
if (res != 0)
|
||||
goto out_null;
|
||||
}
|
||||
|
||||
if (handler && handler->attach) {
|
||||
TRACE_DBG("Calling new dev handler's attach(%p)", dev);
|
||||
res = handler->attach(dev);
|
||||
@@ -933,13 +1058,12 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
PRINT_ERROR_PR("New device handler's %s attach() "
|
||||
"failed: %d", handler->name, res);
|
||||
}
|
||||
goto out_null;
|
||||
goto out_thr_null;
|
||||
}
|
||||
|
||||
if (handler && handler->attach_tgt) {
|
||||
list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
|
||||
dev_tgt_dev_list_entry)
|
||||
{
|
||||
dev_tgt_dev_list_entry) {
|
||||
TRACE_DBG("Calling dev handler's attach_tgt(%p)",
|
||||
tgt_dev);
|
||||
res = handler->attach_tgt(tgt_dev);
|
||||
@@ -953,7 +1077,11 @@ int scst_assign_dev_handler(struct scst_device *dev,
|
||||
&attached_tgt_devs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
out_thr_null:
|
||||
if (res != 0)
|
||||
scst_stop_dev_threads(dev);
|
||||
|
||||
out_null:
|
||||
if (res != 0)
|
||||
dev->handler = NULL;
|
||||
|
||||
@@ -145,33 +145,41 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
struct scst_device *scst_alloc_device(int gfp_mask)
|
||||
/* Called under scst_mutex and suspended activity */
|
||||
int scst_alloc_device(int gfp_mask, struct scst_device **out_dev)
|
||||
{
|
||||
struct scst_device *dev;
|
||||
int res = 0;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
dev = kzalloc(sizeof(*dev), gfp_mask);
|
||||
if (dev == NULL) {
|
||||
TRACE(TRACE_OUT_OF_MEM, "%s",
|
||||
"Allocation of scst_device failed");
|
||||
"Allocation of scst_device failed");
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev->p_cmd_lists = &scst_main_cmd_lists;
|
||||
spin_lock_init(&dev->dev_lock);
|
||||
atomic_set(&dev->on_dev_count, 0);
|
||||
INIT_LIST_HEAD(&dev->blocked_cmd_list);
|
||||
INIT_LIST_HEAD(&dev->dev_tgt_dev_list);
|
||||
INIT_LIST_HEAD(&dev->dev_acg_dev_list);
|
||||
INIT_LIST_HEAD(&dev->threads_list);
|
||||
init_waitqueue_head(&dev->on_dev_waitQ);
|
||||
dev->dev_double_ua_possible = 1;
|
||||
dev->dev_serialized = 1;
|
||||
|
||||
*out_dev = dev;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_HRES(dev);
|
||||
return dev;
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Called under scst_mutex and suspended activity */
|
||||
void scst_free_device(struct scst_device *dev)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
@@ -312,96 +320,6 @@ out:
|
||||
return res;
|
||||
}
|
||||
|
||||
static int scst_create_tgt_threads(struct scst_tgt_dev *tgt_dev)
|
||||
{
|
||||
int i, res = 0;
|
||||
int threads_num = tgt_dev->dev->handler->threads_num +
|
||||
tgt_dev->sess->tgt->tgtt->threads_num;
|
||||
static atomic_t major = ATOMIC_INIT(0);
|
||||
int N, n = 0;
|
||||
char nm[12];
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (tgt_dev->dev->handler->threads_num < 0)
|
||||
threads_num = 0;
|
||||
|
||||
if (threads_num == 0)
|
||||
goto out;
|
||||
|
||||
spin_lock_init(&tgt_dev->cmd_lists.cmd_list_lock);
|
||||
INIT_LIST_HEAD(&tgt_dev->cmd_lists.active_cmd_list);
|
||||
init_waitqueue_head(&tgt_dev->cmd_lists.cmd_list_waitQ);
|
||||
|
||||
if (tgt_dev->dev->handler->threads_num == 0)
|
||||
threads_num += num_online_cpus();
|
||||
|
||||
N = atomic_inc_return(&major);
|
||||
|
||||
for (i = 0; i < threads_num; i++) {
|
||||
struct scst_cmd_thread_t *thr;
|
||||
|
||||
thr = kmalloc(sizeof(*thr), GFP_KERNEL);
|
||||
if (!thr) {
|
||||
res = -ENOMEM;
|
||||
PRINT_ERROR_PR("fail to allocate thr %d", res);
|
||||
goto out;
|
||||
}
|
||||
strncpy(nm, tgt_dev->dev->handler->name, ARRAY_SIZE(nm)-1);
|
||||
nm[ARRAY_SIZE(nm)-1] = '\0';
|
||||
thr->cmd_thread = kthread_run(scst_cmd_thread,
|
||||
&tgt_dev->cmd_lists, "%sd%d_%d", nm, N, n++);
|
||||
if (IS_ERR(thr->cmd_thread)) {
|
||||
res = PTR_ERR(thr->cmd_thread);
|
||||
PRINT_ERROR_PR("kthread_create() failed: %d", res);
|
||||
kfree(thr);
|
||||
goto out;
|
||||
}
|
||||
list_add(&thr->thread_list_entry, &tgt_dev->threads_list);
|
||||
}
|
||||
|
||||
down(&scst_suspend_mutex);
|
||||
list_add_tail(&tgt_dev->cmd_lists.lists_list_entry,
|
||||
&scst_cmd_lists_list);
|
||||
up(&scst_suspend_mutex);
|
||||
|
||||
tgt_dev->p_cmd_lists = &tgt_dev->cmd_lists;
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return res;
|
||||
}
|
||||
|
||||
static void scst_stop_tgt_threads(struct scst_tgt_dev *tgt_dev)
|
||||
{
|
||||
struct scst_cmd_thread_t *ct, *tmp;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (list_empty(&tgt_dev->threads_list))
|
||||
goto out;
|
||||
|
||||
list_for_each_entry_safe(ct, tmp, &tgt_dev->threads_list,
|
||||
thread_list_entry) {
|
||||
int rc = kthread_stop(ct->cmd_thread);
|
||||
if (rc < 0) {
|
||||
TRACE_MGMT_DBG("kthread_stop() failed: %d", rc);
|
||||
}
|
||||
list_del(&ct->thread_list_entry);
|
||||
kfree(ct);
|
||||
}
|
||||
|
||||
if (tgt_dev->p_cmd_lists == &tgt_dev->cmd_lists) {
|
||||
down(&scst_suspend_mutex);
|
||||
list_del(&tgt_dev->cmd_lists.lists_list_entry);
|
||||
up(&scst_suspend_mutex);
|
||||
}
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* No spin locks supposed to be held, scst_mutex - held.
|
||||
* The activity is suspended.
|
||||
@@ -413,6 +331,7 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
struct scst_tgt_dev *tgt_dev;
|
||||
struct scst_device *dev = acg_dev->dev;
|
||||
struct list_head *sess_tgt_dev_list_head;
|
||||
struct scst_tgt_template *vtt = sess->tgt->tgtt;
|
||||
int rc, i;
|
||||
|
||||
TRACE_ENTRY();
|
||||
@@ -431,7 +350,7 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
memset(tgt_dev, 0, sizeof(*tgt_dev));
|
||||
#endif
|
||||
|
||||
tgt_dev->dev = acg_dev->dev;
|
||||
tgt_dev->dev = dev;
|
||||
tgt_dev->lun = acg_dev->lun;
|
||||
tgt_dev->acg_dev = acg_dev;
|
||||
tgt_dev->sess = sess;
|
||||
@@ -440,12 +359,10 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
tgt_dev->gfp_mask = __GFP_NOWARN;
|
||||
tgt_dev->pool = &scst_sgv.norm;
|
||||
|
||||
if (tgt_dev->dev->scsi_dev != NULL) {
|
||||
ini_sg = tgt_dev->dev->scsi_dev->host->sg_tablesize;
|
||||
ini_unchecked_isa_dma =
|
||||
tgt_dev->dev->scsi_dev->host->unchecked_isa_dma;
|
||||
ini_use_clustering =
|
||||
(tgt_dev->dev->scsi_dev->host->use_clustering ==
|
||||
if (dev->scsi_dev != NULL) {
|
||||
ini_sg = dev->scsi_dev->host->sg_tablesize;
|
||||
ini_unchecked_isa_dma = dev->scsi_dev->host->unchecked_isa_dma;
|
||||
ini_use_clustering = (dev->scsi_dev->host->use_clustering ==
|
||||
ENABLE_CLUSTERING);
|
||||
} else {
|
||||
ini_sg = (1 << 15) /* infinite */;
|
||||
@@ -471,8 +388,6 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
#endif
|
||||
}
|
||||
|
||||
tgt_dev->p_cmd_lists = &scst_main_cmd_lists;
|
||||
|
||||
if (dev->scsi_dev != NULL) {
|
||||
TRACE_DBG("host=%d, channel=%d, id=%d, lun=%d, "
|
||||
"SCST lun=%Ld", dev->scsi_dev->host->host_no,
|
||||
@@ -497,7 +412,6 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
tgt_dev->cur_sn_slot = &tgt_dev->sn_slots[0];
|
||||
for(i = 0; i < (int)ARRAY_SIZE(tgt_dev->sn_slots); i++)
|
||||
atomic_set(&tgt_dev->sn_slots[i], 0);
|
||||
INIT_LIST_HEAD(&tgt_dev->threads_list);
|
||||
|
||||
if (dev->handler->parse_atomic &&
|
||||
sess->tgt->tgtt->preprocessing_done_atomic) {
|
||||
@@ -531,9 +445,15 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
|
||||
tm_dbg_init_tgt_dev(tgt_dev, acg_dev);
|
||||
|
||||
rc = scst_create_tgt_threads(tgt_dev);
|
||||
if (rc != 0)
|
||||
goto out_free;
|
||||
if (vtt->threads_num > 0) {
|
||||
rc = 0;
|
||||
if (dev->handler->threads_num > 0)
|
||||
rc = scst_add_dev_threads(dev, vtt->threads_num);
|
||||
else if (dev->handler->threads_num == 0)
|
||||
rc = scst_add_cmd_threads(vtt->threads_num);
|
||||
if (rc != 0)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (dev->handler && dev->handler->attach_tgt) {
|
||||
TRACE_DBG("Calling dev handler's attach_tgt(%p)",
|
||||
@@ -543,7 +463,7 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
|
||||
if (rc != 0) {
|
||||
PRINT_ERROR_PR("Device handler's %s attach_tgt() "
|
||||
"failed: %d", dev->handler->name, rc);
|
||||
goto out_stop_free;
|
||||
goto out_thr_free;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,8 +479,13 @@ out:
|
||||
TRACE_EXIT();
|
||||
return tgt_dev;
|
||||
|
||||
out_stop_free:
|
||||
scst_stop_tgt_threads(tgt_dev);
|
||||
out_thr_free:
|
||||
if (vtt->threads_num > 0) {
|
||||
if (dev->handler->threads_num > 0)
|
||||
scst_del_dev_threads(dev, vtt->threads_num);
|
||||
else if (dev->handler->threads_num == 0)
|
||||
scst_del_cmd_threads(vtt->threads_num);
|
||||
}
|
||||
|
||||
out_free:
|
||||
kmem_cache_free(scst_tgtd_cachep, tgt_dev);
|
||||
@@ -613,6 +538,7 @@ void scst_reset_tgt_dev(struct scst_tgt_dev *tgt_dev, int nexus_loss)
|
||||
static void scst_free_tgt_dev(struct scst_tgt_dev *tgt_dev)
|
||||
{
|
||||
struct scst_device *dev = tgt_dev->dev;
|
||||
struct scst_tgt_template *vtt = tgt_dev->sess->tgt->tgtt;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -631,7 +557,12 @@ static void scst_free_tgt_dev(struct scst_tgt_dev *tgt_dev)
|
||||
TRACE_DBG("%s", "Dev handler's detach_tgt() returned");
|
||||
}
|
||||
|
||||
scst_stop_tgt_threads(tgt_dev);
|
||||
if (vtt->threads_num > 0) {
|
||||
if (dev->handler->threads_num > 0)
|
||||
scst_del_dev_threads(dev, vtt->threads_num);
|
||||
else if (dev->handler->threads_num == 0)
|
||||
scst_del_cmd_threads(vtt->threads_num);
|
||||
}
|
||||
|
||||
kmem_cache_free(scst_tgtd_cachep, tgt_dev);
|
||||
|
||||
@@ -2984,7 +2915,7 @@ void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev,
|
||||
if (!tm_dbg_flags.tm_dbg_active) {
|
||||
/* Do TM debugging only for LUN 0 */
|
||||
tm_dbg_p_cmd_list_waitQ =
|
||||
&tgt_dev->p_cmd_lists->cmd_list_waitQ;
|
||||
&tgt_dev->dev->p_cmd_lists->cmd_list_waitQ;
|
||||
tm_dbg_state = INIT_TM_DBG_STATE;
|
||||
tm_dbg_on_state_passes =
|
||||
tm_dbg_on_state_num_passes[tm_dbg_state];
|
||||
|
||||
@@ -352,7 +352,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size,
|
||||
(obj->sg_entries + pages_to_alloc);
|
||||
TRACE_MEM("trans_tbl %p", obj->trans_tbl);
|
||||
/* We want to have all the data on the same page */
|
||||
EXTRACHECKS_BUG_ON(((unsigned long)obj->sg_entries & PAGE_MASK) !=
|
||||
EXTRACHECKS_WARN_ON_ONCE(((unsigned long)obj->sg_entries & PAGE_MASK) !=
|
||||
((unsigned long)&obj->trans_tbl[pages_to_alloc-1] & PAGE_MASK));
|
||||
/*
|
||||
* No need to clear trans_tbl, if needed, it will
|
||||
@@ -360,7 +360,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size,
|
||||
*/
|
||||
} else {
|
||||
/* We want to have all the data on the same page */
|
||||
EXTRACHECKS_BUG_ON(((unsigned long)obj->sg_entries & PAGE_MASK) !=
|
||||
EXTRACHECKS_WARN_ON_ONCE(((unsigned long)obj->sg_entries & PAGE_MASK) !=
|
||||
((unsigned long)&obj->sg_entries[pages_to_alloc-1] & PAGE_MASK));
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -246,7 +246,10 @@ void scst_cmd_mem_work_fn(void *p);
|
||||
void scst_cmd_mem_work_fn(struct work_struct *work);
|
||||
#endif
|
||||
|
||||
struct scst_device *scst_alloc_device(int gfp_mask);
|
||||
int scst_add_dev_threads(struct scst_device *dev, int num);
|
||||
void scst_del_dev_threads(struct scst_device *dev, int num);
|
||||
|
||||
int scst_alloc_device(int gfp_mask, struct scst_device **out_dev);
|
||||
void scst_free_device(struct scst_device *tgt_dev);
|
||||
|
||||
struct scst_acg *scst_alloc_add_acg(const char *acg_name);
|
||||
|
||||
@@ -2593,7 +2593,7 @@ static int scst_translate_lun(struct scst_cmd *cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
cmd->cmd_lists = tgt_dev->p_cmd_lists;
|
||||
cmd->cmd_lists = tgt_dev->dev->p_cmd_lists;
|
||||
cmd->tgt_dev = tgt_dev;
|
||||
cmd->dev = tgt_dev->dev;
|
||||
|
||||
@@ -4156,8 +4156,7 @@ static int scst_init_session(struct scst_session *sess)
|
||||
|
||||
restart:
|
||||
list_for_each_entry(cmd, &sess->init_deferred_cmd_list,
|
||||
cmd_list_entry)
|
||||
{
|
||||
cmd_list_entry) {
|
||||
TRACE_DBG("Deleting cmd %p from init deferred cmd list", cmd);
|
||||
list_del(&cmd->cmd_list_entry);
|
||||
sess->sess_cmd_count--;
|
||||
@@ -4170,8 +4169,7 @@ restart:
|
||||
|
||||
spin_lock(&scst_mcmd_lock);
|
||||
list_for_each_entry_safe(mcmd, tm, &sess->init_deferred_mcmd_list,
|
||||
mgmt_cmd_list_entry)
|
||||
{
|
||||
mgmt_cmd_list_entry) {
|
||||
TRACE_DBG("Moving mgmt command %p from init deferred mcmd list",
|
||||
mcmd);
|
||||
list_move_tail(&mcmd->mgmt_cmd_list_entry,
|
||||
|
||||
@@ -594,8 +594,10 @@ static int do_sess(struct vdisk_cmd *vcmd)
|
||||
tgt_dev->last_write_cmd_queue_type = SCST_CMD_QUEUE_SIMPLE;
|
||||
|
||||
PRINT_INFO_PR("Session from initiator %s attached (LUN %Lx, "
|
||||
"rd_only %d, sess_h %Lx)", cmd->sess.initiator_name,
|
||||
cmd->sess.lun, cmd->sess.rd_only, cmd->sess.sess_h);
|
||||
"threads_num %d, rd_only %d, sess_h %Lx)",
|
||||
cmd->sess.initiator_name, cmd->sess.lun,
|
||||
cmd->sess.threads_num, cmd->sess.rd_only,
|
||||
cmd->sess.sess_h);
|
||||
} else {
|
||||
if (tgt_dev == NULL) {
|
||||
PRINT_ERROR_PR("Session %Lx not found)", cmd->sess.sess_h);
|
||||
|
||||
Reference in New Issue
Block a user