Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2019-03-09 17:31:56 -08:00
8 changed files with 88 additions and 42 deletions
+7 -5
View File
@@ -1909,7 +1909,7 @@ struct scst_session {
spinlock_t sess_list_lock; /* protects sess_cmd_list, etc */
atomic_t refcnt; /* get/put counter */
struct percpu_ref refcnt; /* get/put counter */
/*
* Alive commands for this session. ToDo: make it part of the common
@@ -2876,11 +2876,13 @@ struct scst_device {
/* Device lock */
spinlock_t dev_lock ____cacheline_aligned_in_smp;
#ifdef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT
/* How many cmds alive on this dev */
atomic_t dev_cmd_count;
#endif
/* One more than the number of commands associated with this device. */
struct percpu_ref dev_cmd_count;
struct work_struct free_work;
struct completion *dev_freed_cmpl;
/*
* Maximum count of uncompleted commands that an initiator could
* queue on this device. Then it will start getting TASK QUEUE FULL
-4
View File
@@ -2547,7 +2547,6 @@ out:
return res;
}
/* scst_mutex supposed to be held and activities suspended */
static int scst_cm_dev_register(struct scst_device *dev, uint64_t lun)
{
int res, i;
@@ -2556,7 +2555,6 @@ static int scst_cm_dev_register(struct scst_device *dev, uint64_t lun)
TRACE_ENTRY();
scst_assert_activity_suspended();
lockdep_assert_held(&scst_mutex);
TRACE_DBG("dev %s, LUN %ld", dev->virt_name, (unsigned long)lun);
@@ -2709,14 +2707,12 @@ out_unblock:
goto out_resume;
}
/* scst_mutex supposed to be held and activities suspended */
int scst_cm_on_dev_register(struct scst_device *dev)
{
int res = 0;
TRACE_ENTRY();
scst_assert_activity_suspended();
lockdep_assert_held(&scst_mutex);
if (!scst_auto_cm_assignment || !dev->handler->auto_cm_assignment_possible)
+65 -12
View File
@@ -4181,15 +4181,41 @@ static int scst_dif_none_type1(struct scst_cmd *cmd);
#define scst_dif_none_type1 scst_dif_none
#endif
/* Called under scst_mutex and suspended activity */
int scst_alloc_device(gfp_t gfp_mask, int nodeid,
struct scst_device **out_dev)
/* Called from thread context and hence may sleep. */
static void scst_finally_free_device(struct work_struct *work)
{
struct scst_device *dev = container_of(work, typeof(*dev),
free_work);
struct completion *c = dev->dev_freed_cmpl;
scst_pr_cleanup(dev);
kfree(dev->virt_name);
percpu_ref_exit(&dev->dev_cmd_count);
kmem_cache_free(scst_dev_cachep, dev);
if (c)
complete(c);
}
/* RCU callback. Must not sleep. */
static void scst_release_device(struct percpu_ref *ref)
{
struct scst_device *dev;
dev = container_of(ref, typeof(*dev), dev_cmd_count);
schedule_work(&dev->free_work);
}
int scst_alloc_device(gfp_t gfp_mask, int nodeid, struct scst_device **out_dev)
{
struct scst_device *dev;
int res = 0;
TRACE_ENTRY();
lockdep_assert_held(&scst_mutex);
dev = kmem_cache_alloc_node(scst_dev_cachep, gfp_mask, nodeid);
if (dev == NULL) {
PRINT_ERROR("%s", "Allocation of scst_device failed");
@@ -4199,8 +4225,13 @@ int scst_alloc_device(gfp_t gfp_mask, int nodeid,
memset(dev, 0, sizeof(*dev));
dev->handler = &scst_null_devtype;
#ifdef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT
atomic_set(&dev->dev_cmd_count, 0);
INIT_WORK(&dev->free_work, scst_finally_free_device);
res = percpu_ref_init(&dev->dev_cmd_count, scst_release_device,
PERCPU_REF_INIT_ATOMIC, GFP_KERNEL);
if (res < 0)
goto free_dev;
#ifndef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT
percpu_ref_switch_to_percpu(&dev->dev_cmd_count);
#endif
scst_init_mem_lim(&dev->dev_mem_lim);
spin_lock_init(&dev->dev_lock);
@@ -4234,10 +4265,16 @@ int scst_alloc_device(gfp_t gfp_mask, int nodeid,
out:
TRACE_EXIT_RES(res);
return res;
free_dev:
kmem_cache_free(scst_dev_cachep, dev);
goto out;
}
void scst_free_device(struct scst_device *dev)
{
DECLARE_COMPLETION_ONSTACK(c);
TRACE_ENTRY();
EXTRACHECKS_BUG_ON(dev->dev_scsi_atomic_cmd_active != 0);
@@ -4257,11 +4294,11 @@ void scst_free_device(struct scst_device *dev)
scst_deinit_threads(&dev->dev_cmd_threads);
scst_pr_cleanup(dev);
kfree(dev->virt_name);
kmem_cache_free(scst_dev_cachep, dev);
dev->dev_freed_cmpl = &c;
percpu_ref_kill(&dev->dev_cmd_count);
wait_for_completion(&c);
TRACE_EXIT();
return;
}
@@ -6995,11 +7032,18 @@ static void scst_clear_reservation(struct scst_tgt_dev *tgt_dev)
return;
}
static void scst_sess_release(struct percpu_ref *ref)
{
struct scst_session *sess = container_of(ref, typeof(*sess), refcnt);
scst_sched_session_free(sess);
}
struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask,
const char *initiator_name)
{
struct scst_session *sess;
int i;
int i, ret;
TRACE_ENTRY();
@@ -7011,7 +7055,11 @@ struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask,
sess->init_phase = SCST_SESS_IPH_INITING;
sess->shut_phase = SCST_SESS_SPH_READY;
atomic_set(&sess->refcnt, 0);
ret = percpu_ref_init(&sess->refcnt, scst_sess_release,
PERCPU_REF_INIT_ATOMIC, GFP_KERNEL);
if (ret < 0)
goto out_free;
percpu_ref_switch_to_percpu(&sess->refcnt);
mutex_init(&sess->tgt_dev_list_mutex);
for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
struct list_head *head = &sess->sess_tgt_dev_list[i];
@@ -7038,7 +7086,7 @@ struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask,
sess->initiator_name = kstrdup(initiator_name, gfp_mask);
if (sess->initiator_name == NULL) {
PRINT_ERROR("%s", "Unable to dup sess->initiator_name");
goto out_free;
goto out_free_refcnt;
}
if (atomic_read(&scst_measure_latency)) {
@@ -7054,6 +7102,9 @@ out:
out_free_name:
kfree(sess->initiator_name);
out_free_refcnt:
percpu_ref_exit(&sess->refcnt);
out_free:
kmem_cache_free(scst_sess_cachep, sess);
sess = NULL;
@@ -7103,6 +7154,8 @@ void scst_free_session(struct scst_session *sess)
if (sess->sess_name != sess->initiator_name)
kfree(sess->sess_name);
percpu_ref_exit(&sess->refcnt);
kmem_cache_free(scst_sess_cachep, sess);
TRACE_EXIT();
+2 -5
View File
@@ -1347,10 +1347,6 @@ int scst_register_virtual_device_node(struct scst_dev_type *dev_handler,
if (res != 0)
goto out;
res = scst_suspend_activity(SCST_SUSPEND_TIMEOUT_USER);
if (res != 0)
goto out;
res = mutex_lock_interruptible(&scst_mutex);
if (res != 0)
goto out_resume;
@@ -1419,7 +1415,6 @@ int scst_register_virtual_device_node(struct scst_dev_type *dev_handler,
goto out_unreg;
mutex_unlock(&scst_mutex);
scst_resume_activity();
res = dev->virt_id;
@@ -2681,6 +2676,8 @@ static void __exit exit_scst(void)
scst_event_exit();
rcu_barrier();
#define DEINIT_CACHEP(p) do { \
kmem_cache_destroy(p); \
p = NULL; \
+2 -7
View File
@@ -720,17 +720,12 @@ void scst_sched_session_free(struct scst_session *sess);
static inline void scst_sess_get(struct scst_session *sess)
{
atomic_inc(&sess->refcnt);
TRACE_DBG("Incrementing sess %p refcnt (new value %d)",
sess, atomic_read(&sess->refcnt));
percpu_ref_get(&sess->refcnt);
}
static inline void scst_sess_put(struct scst_session *sess)
{
TRACE_DBG("Decrementing sess %p refcnt (new value %d)",
sess, atomic_read(&sess->refcnt)-1);
if (atomic_dec_and_test(&sess->refcnt))
scst_sched_session_free(sess);
percpu_ref_put(&sess->refcnt);
}
struct scst_cmd *scst_alloc_cmd(const uint8_t *cdb,
+7 -7
View File
@@ -4503,9 +4503,7 @@ static int scst_pre_xmit_response1(struct scst_cmd *cmd)
*/
smp_mb__before_atomic_dec();
atomic_dec(&cmd->tgt_dev->tgt_dev_cmd_count);
#ifdef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT
atomic_dec(&cmd->dev->dev_cmd_count);
#endif
percpu_ref_put(&cmd->dev->dev_cmd_count);
if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
scst_on_hq_cmd_response(cmd);
else if (unlikely(!cmd->sent_for_exec)) {
@@ -5134,6 +5132,7 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
if (likely(res == 0)) {
struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
struct scst_device *dev = cmd->dev;
unsigned long __percpu *a __maybe_unused;
bool failure = false;
int cnt;
@@ -5149,8 +5148,10 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
failure = true;
}
percpu_ref_get(&dev->dev_cmd_count);
#ifdef CONFIG_SCST_PER_DEVICE_CMD_COUNT_LIMIT
cnt = atomic_inc_return(&dev->dev_cmd_count);
sBUG_ON(__ref_is_percpu(&dev->dev_cmd_count, &a));
cnt = atomic_long_read(&dev->dev_cmd_count.count);
if (unlikely(cnt > SCST_MAX_DEV_COMMANDS)) {
if (!failure) {
TRACE(TRACE_FLOW_CONTROL,
@@ -8173,7 +8174,6 @@ static struct scst_session *__scst_register_session(struct scst_tgt *tgt, int at
scst_sess_set_tgt_priv(sess, tgt_priv);
sess->sess_mq = mq;
scst_sess_get(sess); /* one for registered session */
scst_sess_get(sess); /* one held until sess is inited */
if (atomic) {
@@ -8372,7 +8372,7 @@ void scst_unregister_session(struct scst_session *sess, int wait,
spin_unlock_irqrestore(&scst_mgmt_lock, flags);
scst_sess_put(sess);
percpu_ref_kill(&sess->refcnt);
if (wait) {
TRACE_DBG("Waiting for session %p to complete", sess);
@@ -8464,7 +8464,7 @@ int scst_global_mgmt_thread(void *arg)
switch (sess->shut_phase) {
case SCST_SESS_SPH_SHUTDOWN:
sBUG_ON(atomic_read(&sess->refcnt) != 0);
sBUG_ON(!percpu_ref_is_zero(&sess->refcnt));
scst_free_session_callback(sess);
break;
default:
@@ -7,11 +7,12 @@ package SCST::SCST;
# Copyright (c) 2005-2011 Mark R. Buechler
# Copyright (c) 2011-2019 Bart Van Assche <bvanassche@acm.org>.
use strict;
use warnings;
use 5.005;
use Fcntl ':mode';
use IO::Handle;
use IO::File;
use strict;
use Carp qw(cluck);
use POSIX;
+3 -1
View File
@@ -1,5 +1,8 @@
#!/usr/bin/perl
use strict;
use warnings;
my $Version = 'SCST Configurator v3.3.0-pre1';
# Configures SCST
@@ -242,7 +245,6 @@ Examples:
EndUsage
}
use strict;
use Cwd qw(abs_path);
use File::Basename;
use File::Spec;