Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2017-05-12 21:23:32 -07:00
13 changed files with 754 additions and 5 deletions

View File

@@ -482,7 +482,11 @@ static void ft_sess_free(struct kref *kref)
static void ft_sess_put(struct ft_sess *sess)
{
BUG_ON(!sess);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
BUG_ON(kref_read(&sess->kref) <= 0);
#else
BUG_ON(atomic_read(&sess->kref.refcount) <= 0);
#endif
kref_put(&sess->kref, ft_sess_free);
}

File diff suppressed because it is too large Load Diff

View File

@@ -27,6 +27,10 @@
#include <linux/aer.h>
#include <linux/mutex.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
#include <linux/bsg-lib.h>
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
#error
#error ***This version of qla2xxx does not support distributions based on***
@@ -289,7 +293,11 @@ typedef struct srb {
int iocbs;
union {
struct srb_iocb iocb_cmd;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
struct fc_bsg_job *bsg_job;
#else
struct bsg_job *bsg_job;
#endif
struct srb_cmd scmd;
} u;
void (*done)(void *, void *, int);

View File

@@ -604,8 +604,13 @@ extern int qla82xx_mbx_beacon_ctl(scsi_qla_host_t *, int);
extern void qla82xx_clear_pending_mbx(scsi_qla_host_t *);
/* BSG related functions */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
extern int qla24xx_bsg_request(struct bsg_job *);
extern int qla24xx_bsg_timeout(struct bsg_job *);
#else
extern int qla24xx_bsg_request(struct fc_bsg_job *);
extern int qla24xx_bsg_timeout(struct fc_bsg_job *);
#endif
extern int qla84xx_reset_chip(scsi_qla_host_t *, uint16_t);
extern int qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *,
dma_addr_t, size_t, uint32_t);

View File

@@ -2105,7 +2105,12 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
static void
qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
#else
struct bsg_job *bsg_job = sp->u.bsg_job;
struct fc_bsg_request *bsg_request = bsg_job->request;
#endif
els_iocb->entry_type = ELS_IOCB_TYPE;
els_iocb->entry_count = 1;
@@ -2120,8 +2125,13 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
els_iocb->opcode =
sp->type == SRB_ELS_CMD_RPT ?
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->request->rqst_data.r_els.els_code :
bsg_job->request->rqst_data.h_els.command_code;
#else
bsg_request->rqst_data.r_els.els_code :
bsg_request->rqst_data.h_els.command_code;
#endif
els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
els_iocb->port_id[1] = sp->fcport->d_id.b.area;
els_iocb->port_id[2] = sp->fcport->d_id.b.domain;
@@ -2156,7 +2166,11 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb)
uint16_t tot_dsds;
scsi_qla_host_t *vha = sp->fcport->vha;
struct qla_hw_data *ha = vha->hw;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
#else
struct bsg_job *bsg_job = sp->u.bsg_job;
#endif
int loop_iterartion = 0;
int cont_iocb_prsnt = 0;
int entry_count = 1;
@@ -2233,7 +2247,11 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
uint16_t tot_dsds;
scsi_qla_host_t *vha = sp->fcport->vha;
struct qla_hw_data *ha = vha->hw;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
#else
struct bsg_job *bsg_job = sp->u.bsg_job;
#endif
int loop_iterartion = 0;
int cont_iocb_prsnt = 0;
int entry_count = 1;

View File

@@ -1080,7 +1080,12 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
const char func[] = "CT_IOCB";
const char *type;
srb_t *sp;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
struct fc_bsg_job *bsg_job;
#else
struct bsg_job *bsg_job;
struct fc_bsg_reply *bsg_reply;
#endif
uint16_t comp_status;
int res;
@@ -1089,6 +1094,9 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
return;
bsg_job = sp->u.bsg_job;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
bsg_reply = bsg_job->reply;
#endif
type = "ct pass-through";
@@ -1097,32 +1105,52 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
* fc payload to the caller
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
#else
bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
#endif
bsg_job->reply_len = sizeof(struct fc_bsg_reply);
if (comp_status != CS_COMPLETE) {
if (comp_status == CS_DATA_UNDERRUN) {
res = DID_OK << 16;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->reply->reply_payload_rcv_len =
#else
bsg_reply->reply_payload_rcv_len =
#endif
le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
ql_log(ql_log_warn, vha, 0x5048,
"CT pass-through-%s error "
"comp_status-status=0x%x total_byte = 0x%x.\n",
type, comp_status,
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->reply->reply_payload_rcv_len);
#else
bsg_reply->reply_payload_rcv_len);
#endif
} else {
ql_log(ql_log_warn, vha, 0x5049,
"CT pass-through-%s error "
"comp_status-status=0x%x.\n", type, comp_status);
res = DID_ERROR << 16;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->reply->reply_payload_rcv_len = 0;
#else
bsg_reply->reply_payload_rcv_len = 0;
#endif
}
ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035,
(uint8_t *)pkt, sizeof(*pkt));
} else {
res = DID_OK << 16;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->reply->reply_payload_rcv_len =
#else
bsg_reply->reply_payload_rcv_len =
#endif
bsg_job->reply_payload.payload_len;
bsg_job->reply_len = 0;
}
@@ -1136,7 +1164,12 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
const char func[] = "ELS_CT_IOCB";
const char *type;
srb_t *sp;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
struct fc_bsg_job *bsg_job;
#else
struct bsg_job *bsg_job;
struct fc_bsg_reply *bsg_reply;
#endif
uint16_t comp_status;
uint32_t fw_status[3];
uint8_t* fw_sts_ptr;
@@ -1146,6 +1179,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
if (!sp)
return;
bsg_job = sp->u.bsg_job;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
bsg_reply = bsg_job->reply;
#endif
type = NULL;
switch (sp->type) {
@@ -1169,13 +1205,21 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
* fc payload to the caller
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
#else
bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
#endif
bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(fw_status);
if (comp_status != CS_COMPLETE) {
if (comp_status == CS_DATA_UNDERRUN) {
res = DID_OK << 16;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->reply->reply_payload_rcv_len =
#else
bsg_reply->reply_payload_rcv_len =
#endif
le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count);
ql_dbg(ql_dbg_user, vha, 0x503f,
@@ -1197,7 +1241,11 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
le16_to_cpu(((struct els_sts_entry_24xx *)
pkt)->error_subcode_2));
res = DID_ERROR << 16;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->reply->reply_payload_rcv_len = 0;
#else
bsg_reply->reply_payload_rcv_len = 0;
#endif
fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
}
@@ -1206,7 +1254,11 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
}
else {
res = DID_OK << 16;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
#else
bsg_reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
#endif
bsg_job->reply_len = 0;
}
sp->done(vha, sp, 0);

View File

@@ -398,6 +398,16 @@ Module scst supports the following parameters:
to be consumed by all SCSI commands of a device at any given time. By
default, it is approximately 2/5 of scst_max_cmd_mem.
- auto_cm_assignment - enables the copy managers auto registration.
If a device is not registered in the copy manager, it can not be
source or target of EXTENDED COPY commands. Enabled by default.
Disable, if you want to manually control the copy manager
registration or need to change a device, e.g. a DM cache device, with
SCST LUN on top of it to avoid extra reference the copy manager holds
on this device. In the later case you can also remove this reference
by manually deleting the corresponding copy manager LUN via sysfs interface
(/sys/kernel/scst_tgt/targets/copy_manager/copy_manager_tgt/luns/mgmt).
SCST sysfs interface
--------------------

View File

@@ -268,6 +268,16 @@ Module scst supports the following parameters:
consumed by the SCST commands for data buffers at any given time. By
default it is approximately TotalMem/4.
- auto_cm_assignment - enables the copy managers auto registration.
If a device is not registered in the copy manager, it can not be
source or target of EXTENDED COPY commands. Enabled by default.
Disable, if you want to manually control the copy manager
registration or need to change a device, e.g. a DM cache device, with
SCST LUN on top of it to avoid extra reference the copy manager holds
on this device. In the later case you can also remove this reference
by manually deleting the corresponding copy manager LUN via sysfs interface
(/sys/kernel/scst_tgt/targets/copy_manager/copy_manager_tgt/luns/mgmt).
SCST sysfs interface
--------------------

View File

@@ -0,0 +1,114 @@
=== modified file 'include/linux/lockdep.h'
--- old/include/linux/lockdep.h 2017-05-04 04:27:46 +0000
+++ new/include/linux/lockdep.h 2017-05-04 04:39:00 +0000
@@ -373,7 +373,7 @@ extern struct pin_cookie lock_pin_lock(s
extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie);
extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
-# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0,
+# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, .nolockdep_call = 0,
#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
=== modified file 'include/linux/sched.h'
--- old/include/linux/sched.h 2017-05-04 04:27:46 +0000
+++ new/include/linux/sched.h 2017-05-04 04:39:00 +0000
@@ -1789,6 +1789,9 @@ struct task_struct {
# define MAX_LOCK_DEPTH 48UL
u64 curr_chain_key;
int lockdep_depth;
+# define NOLOCKDEP_SUPPORTED 1
+ unsigned int nolockdep_call:1;
+ unsigned int nolockdep_call_irq_saved:1;
unsigned int lockdep_recursion;
struct held_lock held_locks[MAX_LOCK_DEPTH];
gfp_t lockdep_reclaim_gfp;
=== modified file 'kernel/locking/lockdep.c'
--- old/kernel/locking/lockdep.c 2017-05-04 04:27:46 +0000
+++ new/kernel/locking/lockdep.c 2017-05-04 04:39:00 +0000
@@ -3745,9 +3745,11 @@ void lock_acquire(struct lockdep_map *lo
if (unlikely(current->lockdep_recursion))
return;
+ if (unlikely(current->nolockdep_call))
+ return;
+
raw_local_irq_save(flags);
check_flags(flags);
-
current->lockdep_recursion = 1;
trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
__lock_acquire(lock, subclass, trylock, read, check,
@@ -3765,6 +3767,9 @@ void lock_release(struct lockdep_map *lo
if (unlikely(current->lockdep_recursion))
return;
+ if (unlikely(current->nolockdep_call))
+ return;
+
raw_local_irq_save(flags);
check_flags(flags);
current->lockdep_recursion = 1;
@@ -4013,6 +4018,9 @@ void lock_contended(struct lockdep_map *
if (unlikely(current->lockdep_recursion))
return;
+ if (unlikely(current->nolockdep_call))
+ return;
+
raw_local_irq_save(flags);
check_flags(flags);
current->lockdep_recursion = 1;
@@ -4033,6 +4041,9 @@ void lock_acquired(struct lockdep_map *l
if (unlikely(current->lockdep_recursion))
return;
+ if (unlikely(current->nolockdep_call))
+ return;
+
raw_local_irq_save(flags);
check_flags(flags);
current->lockdep_recursion = 1;
=== modified file 'kernel/softirq.c'
--- old/kernel/softirq.c 2017-05-04 04:27:46 +0000
+++ new/kernel/softirq.c 2017-05-04 04:39:00 +0000
@@ -335,6 +335,17 @@ asmlinkage __visible void do_softirq(voi
*/
void irq_enter(void)
{
+#ifdef CONFIG_LOCKDEP
+ if (unlikely(current->nolockdep_call)) {
+ unsigned long flags;
+ local_irq_save(flags);
+ if (current->nolockdep_call) {
+ current->nolockdep_call_irq_saved = 1;
+ current->nolockdep_call = 0;
+ }
+ local_irq_restore(flags);
+ }
+#endif
rcu_irq_enter();
if (is_idle_task(current) && !in_interrupt()) {
/*
@@ -406,6 +417,17 @@ void irq_exit(void)
tick_irq_exit();
rcu_irq_exit();
+#ifdef CONFIG_LOCKDEP
+ if (unlikely(current->nolockdep_call_irq_saved)) {
+ unsigned long flags;
+ local_irq_save(flags);
+ if (current->nolockdep_call_irq_saved) {
+ current->nolockdep_call_irq_saved = 0;
+ current->nolockdep_call = 1;
+ }
+ local_irq_restore(flags);
+ }
+#endif
trace_hardirq_exit(); /* must be last! */
}

View File

@@ -2718,7 +2718,7 @@ int scst_cm_on_dev_register(struct scst_device *dev)
scst_assert_activity_suspended();
lockdep_assert_held(&scst_mutex);
if (!dev->handler->auto_cm_assignment_possible)
if (!scst_auto_cm_assignment || !dev->handler->auto_cm_assignment_possible)
goto out;
res = scst_cm_dev_register(dev, SCST_MAX_LUN);

View File

@@ -175,6 +175,7 @@ cpumask_t default_cpu_mask;
static unsigned int scst_max_cmd_mem;
unsigned int scst_max_dev_cmd_mem;
int scst_forcibly_close_sessions;
int scst_auto_cm_assignment = true;
module_param_named(scst_threads, scst_threads, int, S_IRUGO);
MODULE_PARM_DESC(scst_threads, "SCSI target threads count");
@@ -193,6 +194,9 @@ MODULE_PARM_DESC(forcibly_close_sessions,
"If enabled, close the sessions associated with an access control group (ACG)"
" when an ACG is deleted via sysfs instead of returning -EBUSY");
module_param_named(auto_cm_assignment, scst_auto_cm_assignment, int,
S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(auto_cm_assignment, "Enables the copy managers auto registration");
struct scst_dev_type scst_null_devtype = {
.name = "none",

View File

@@ -152,6 +152,7 @@ extern int scst_threads;
extern unsigned int scst_max_dev_cmd_mem;
extern int scst_forcibly_close_sessions;
extern int scst_auto_cm_assignment;
extern mempool_t *scst_mgmt_mempool;
extern mempool_t *scst_mgmt_stub_mempool;

View File

@@ -4712,6 +4712,7 @@ static int scst_finish_cmd(struct scst_cmd *cmd)
struct scst_session *sess = cmd->sess;
struct scst_io_stat_entry *stat;
int block_shift, align_len;
uint64_t lba;
TRACE_ENTRY();
@@ -4744,12 +4745,14 @@ static int scst_finish_cmd(struct scst_cmd *cmd)
block_shift = cmd->dev->block_shift;
/* Let's track only 4K unaligned cmds at the moment */
align_len = (block_shift != 0) ? 4095 : 0;
lba = cmd->lba;
} else {
block_shift = 0;
align_len = 0;
lba = 0;
}
if (unlikely(((cmd->lba << block_shift) & align_len) != 0) ||
if (unlikely(((lba << block_shift) & align_len) != 0) ||
unlikely(((cmd->bufflen + cmd->out_bufflen) & align_len) != 0))
stat->unaligned_cmd_count++;