Skip to content

Commit

Permalink
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/nab/target-pending

Pull SCSI target updates from Nicholas Bellinger:
 "Here are the target pending updates for v3.15-rc1.  Apologies in
  advance for waiting until the second to last day of the merge window
  to send these out.

  The highlights this round include:

   - iser-target support for T10 PI (DIF) offloads (Sagi + Or)
   - Fix Task Aborted Status (TAS) handling in target-core (Alex Leung)
   - Pass in transport supported PI at session initialization (Sagi + MKP + nab)
   - Add WRITE_INSERT + READ_STRIP T10 PI support in target-core (nab + Sagi)
   - Fix iscsi-target ERL=2 ASYNC_EVENT connection pointer bug (nab)
   - Fix tcm_fc use-after-free of ft_tpg (Andy Grover)
   - Use correct ib_sg_dma primitives in ib_isert (Mike Marciniszyn)

  Also, note the virtio-scsi + vhost-scsi changes to expose T10 PI
  metadata into KVM guest have been left-out for now, as there where a
  few comments from MST + Paolo that where not able to be addressed in
  time for v3.15.  Please expect this feature for v3.16-rc1"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (43 commits)
  ib_srpt: Use correct ib_sg_dma primitives
  target/tcm_fc: Rename ft_tport_create to ft_tport_get
  target/tcm_fc: Rename ft_{add,del}_lport to {add,del}_wwn
  target/tcm_fc: Rename structs and list members for clarity
  target/tcm_fc: Limit to 1 TPG per wwn
  target/tcm_fc: Don't export ft_lport_list
  target/tcm_fc: Fix use-after-free of ft_tpg
  target: Add check to prevent Abort Task from aborting itself
  target: Enable READ_STRIP emulation in target_complete_ok_work
  target/sbc: Add sbc_dif_read_strip software emulation
  target: Enable WRITE_INSERT emulation in target_execute_cmd
  target/sbc: Add sbc_dif_generate software emulation
  target/sbc: Only expose PI read_cap16 bits when supported by fabric
  target/spc: Only expose PI mode page bits when supported by fabric
  target/spc: Only expose PI inquiry bits when supported by fabric
  target: Pass in transport supported PI at session initialization
  target/iblock: Fix double bioset_integrity_free bug
  Target/sbc: Initialize COMPARE_AND_WRITE write_sg scatterlist
  target/rd: T10-Dif: RAM disk is allocating more space than required.
  iscsi-target: Fix ERL=2 ASYNC_EVENT connection pointer bug
  ...
  • Loading branch information
torvalds committed Apr 12, 2014
2 parents 9309444 + b076808 commit 141eacc
Show file tree
Hide file tree
Showing 33 changed files with 1,241 additions and 437 deletions.
828 changes: 639 additions & 189 deletions drivers/infiniband/ulp/isert/ib_isert.c

Large diffs are not rendered by default.

38 changes: 31 additions & 7 deletions drivers/infiniband/ulp/isert/ib_isert.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,35 @@ struct iser_tx_desc {
struct ib_send_wr send_wr;
} __packed;

enum isert_indicator {
ISERT_PROTECTED = 1 << 0,
ISERT_DATA_KEY_VALID = 1 << 1,
ISERT_PROT_KEY_VALID = 1 << 2,
ISERT_SIG_KEY_VALID = 1 << 3,
};

struct pi_context {
struct ib_mr *prot_mr;
struct ib_fast_reg_page_list *prot_frpl;
struct ib_mr *sig_mr;
};

struct fast_reg_descriptor {
struct list_head list;
struct ib_mr *data_mr;
struct ib_fast_reg_page_list *data_frpl;
bool valid;
struct list_head list;
struct ib_mr *data_mr;
struct ib_fast_reg_page_list *data_frpl;
u8 ind;
struct pi_context *pi_ctx;
};

struct isert_data_buf {
struct scatterlist *sg;
int nents;
u32 sg_off;
u32 len; /* cur_rdma_length */
u32 offset;
unsigned int dma_nents;
enum dma_data_direction dma_dir;
};

struct isert_rdma_wr {
Expand All @@ -63,12 +87,11 @@ struct isert_rdma_wr {
enum iser_ib_op_code iser_ib_op;
struct ib_sge *ib_sge;
struct ib_sge s_ib_sge;
int num_sge;
struct scatterlist *sge;
int send_wr_num;
struct ib_send_wr *send_wr;
struct ib_send_wr s_send_wr;
u32 cur_rdma_length;
struct isert_data_buf data;
struct isert_data_buf prot;
struct fast_reg_descriptor *fr_desc;
};

Expand Down Expand Up @@ -141,6 +164,7 @@ struct isert_cq_desc {

struct isert_device {
int use_fastreg;
bool pi_capable;
int cqs_used;
int refcount;
int cq_active_qps[ISERT_MAX_CQ];
Expand Down
27 changes: 20 additions & 7 deletions drivers/infiniband/ulp/srpt/ib_srpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,7 @@ static void srpt_unmap_sg_to_ib_sge(struct srpt_rdma_ch *ch,
static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
struct srpt_send_ioctx *ioctx)
{
struct ib_device *dev = ch->sport->sdev->device;
struct se_cmd *cmd;
struct scatterlist *sg, *sg_orig;
int sg_cnt;
Expand Down Expand Up @@ -1124,7 +1125,7 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,

db = ioctx->rbufs;
tsize = cmd->data_length;
dma_len = sg_dma_len(&sg[0]);
dma_len = ib_sg_dma_len(dev, &sg[0]);
riu = ioctx->rdma_ius;

/*
Expand Down Expand Up @@ -1155,7 +1156,8 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
++j;
if (j < count) {
sg = sg_next(sg);
dma_len = sg_dma_len(sg);
dma_len = ib_sg_dma_len(
dev, sg);
}
}
} else {
Expand Down Expand Up @@ -1192,8 +1194,8 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
tsize = cmd->data_length;
riu = ioctx->rdma_ius;
sg = sg_orig;
dma_len = sg_dma_len(&sg[0]);
dma_addr = sg_dma_address(&sg[0]);
dma_len = ib_sg_dma_len(dev, &sg[0]);
dma_addr = ib_sg_dma_address(dev, &sg[0]);

/* this second loop is really mapped sg_addres to rdma_iu->ib_sge */
for (i = 0, j = 0;
Expand All @@ -1216,8 +1218,10 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch,
++j;
if (j < count) {
sg = sg_next(sg);
dma_len = sg_dma_len(sg);
dma_addr = sg_dma_address(sg);
dma_len = ib_sg_dma_len(
dev, sg);
dma_addr = ib_sg_dma_address(
dev, sg);
}
}
} else {
Expand Down Expand Up @@ -2580,7 +2584,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
goto destroy_ib;
}

ch->sess = transport_init_session();
ch->sess = transport_init_session(TARGET_PROT_NORMAL);
if (IS_ERR(ch->sess)) {
rej->reason = __constant_cpu_to_be32(
SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);
Expand Down Expand Up @@ -3081,6 +3085,14 @@ static void srpt_queue_tm_rsp(struct se_cmd *cmd)
srpt_queue_response(cmd);
}

static void srpt_aborted_task(struct se_cmd *cmd)
{
struct srpt_send_ioctx *ioctx = container_of(cmd,
struct srpt_send_ioctx, cmd);

srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx);
}

static int srpt_queue_status(struct se_cmd *cmd)
{
struct srpt_send_ioctx *ioctx;
Expand Down Expand Up @@ -3928,6 +3940,7 @@ static struct target_core_fabric_ops srpt_template = {
.queue_data_in = srpt_queue_data_in,
.queue_status = srpt_queue_status,
.queue_tm_rsp = srpt_queue_tm_rsp,
.aborted_task = srpt_aborted_task,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
Expand Down
18 changes: 17 additions & 1 deletion drivers/scsi/qla2xxx/tcm_qla2xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,20 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd)
qlt_xmit_tm_rsp(mcmd);
}

static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
{
struct qla_tgt_cmd *cmd = container_of(se_cmd,
struct qla_tgt_cmd, se_cmd);
struct scsi_qla_host *vha = cmd->vha;
struct qla_hw_data *ha = vha->hw;

if (!cmd->sg_mapped)
return;

pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
cmd->sg_mapped = 0;
}

/* Local pointer to allocated TCM configfs fabric module */
struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;
Expand Down Expand Up @@ -1468,7 +1482,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
}
se_tpg = &tpg->se_tpg;

se_sess = transport_init_session();
se_sess = transport_init_session(TARGET_PROT_NORMAL);
if (IS_ERR(se_sess)) {
pr_err("Unable to initialize struct se_session\n");
return PTR_ERR(se_sess);
Expand Down Expand Up @@ -1877,6 +1891,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = {
.queue_data_in = tcm_qla2xxx_queue_data_in,
.queue_status = tcm_qla2xxx_queue_status,
.queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp,
.aborted_task = tcm_qla2xxx_aborted_task,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
Expand Down Expand Up @@ -1926,6 +1941,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = {
.queue_data_in = tcm_qla2xxx_queue_data_in,
.queue_status = tcm_qla2xxx_queue_status,
.queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp,
.aborted_task = tcm_qla2xxx_aborted_task,
/*
* Setup function pointers for generic logic in
* target_core_fabric_configfs.c
Expand Down
33 changes: 32 additions & 1 deletion drivers/target/iscsi/iscsi_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,23 @@ static int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
return 0;
}

static void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
{
bool scsi_cmd = (cmd->iscsi_opcode == ISCSI_OP_SCSI_CMD);

spin_lock_bh(&conn->cmd_lock);
if (!list_empty(&cmd->i_conn_node))
list_del_init(&cmd->i_conn_node);
spin_unlock_bh(&conn->cmd_lock);

__iscsit_free_cmd(cmd, scsi_cmd, true);
}

static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsi_conn *conn)
{
return TARGET_PROT_NORMAL;
}

static struct iscsit_transport iscsi_target_transport = {
.name = "iSCSI/TCP",
.transport_type = ISCSI_TCP,
Expand All @@ -513,6 +530,8 @@ static struct iscsit_transport iscsi_target_transport = {
.iscsit_response_queue = iscsit_response_queue,
.iscsit_queue_data_in = iscsit_queue_rsp,
.iscsit_queue_status = iscsit_queue_rsp,
.iscsit_aborted_task = iscsit_aborted_task,
.iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops,
};

static int __init iscsi_target_init_module(void)
Expand Down Expand Up @@ -1503,6 +1522,16 @@ int iscsit_setup_nop_out(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
{
u32 payload_length = ntoh24(hdr->dlength);

if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL)) {
pr_err("NopOUT Flag's, Left Most Bit not set, protocol error.\n");
if (!cmd)
return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
(unsigned char *)hdr);

return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
(unsigned char *)hdr);
}

if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
" not set, protocol error.\n");
Expand Down Expand Up @@ -2468,6 +2497,7 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn)
{
struct iscsi_cmd *cmd;
struct iscsi_conn *conn_p;
bool found = false;

/*
* Only send a Asynchronous Message on connections whos network
Expand All @@ -2476,11 +2506,12 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn)
list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) {
if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) {
iscsit_inc_conn_usage_count(conn_p);
found = true;
break;
}
}

if (!conn_p)
if (!found)
return;

cmd = iscsit_allocate_cmd(conn_p, TASK_RUNNING);
Expand Down
14 changes: 14 additions & 0 deletions drivers/target/iscsi/iscsi_target_configfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,11 @@ TPG_ATTR(demo_mode_discovery, S_IRUGO | S_IWUSR);
*/
DEF_TPG_ATTRIB(default_erl);
TPG_ATTR(default_erl, S_IRUGO | S_IWUSR);
/*
* Define iscsi_tpg_attrib_s_t10_pi
*/
DEF_TPG_ATTRIB(t10_pi);
TPG_ATTR(t10_pi, S_IRUGO | S_IWUSR);

static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
&iscsi_tpg_attrib_authentication.attr,
Expand All @@ -1064,6 +1069,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
&iscsi_tpg_attrib_prod_mode_write_protect.attr,
&iscsi_tpg_attrib_demo_mode_discovery.attr,
&iscsi_tpg_attrib_default_erl.attr,
&iscsi_tpg_attrib_t10_pi.attr,
NULL,
};

Expand Down Expand Up @@ -1815,6 +1821,13 @@ static void lio_queue_tm_rsp(struct se_cmd *se_cmd)
iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
}

static void lio_aborted_task(struct se_cmd *se_cmd)
{
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);

cmd->conn->conn_transport->iscsit_aborted_task(cmd->conn, cmd);
}

static char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg)
{
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
Expand Down Expand Up @@ -1999,6 +2012,7 @@ int iscsi_target_register_configfs(void)
fabric->tf_ops.queue_data_in = &lio_queue_data_in;
fabric->tf_ops.queue_status = &lio_queue_status;
fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp;
fabric->tf_ops.aborted_task = &lio_aborted_task;
/*
* Setup function pointers for generic logic in target_core_fabric_configfs.c
*/
Expand Down
5 changes: 4 additions & 1 deletion drivers/target/iscsi/iscsi_target_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
#define TA_DEMO_MODE_DISCOVERY 1
#define TA_DEFAULT_ERL 0
#define TA_CACHE_CORE_NPS 0

/* T10 protection information disabled by default */
#define TA_DEFAULT_T10_PI 0

#define ISCSI_IOV_DATA_BUFFER 5

Expand Down Expand Up @@ -765,6 +766,7 @@ struct iscsi_tpg_attrib {
u32 prod_mode_write_protect;
u32 demo_mode_discovery;
u32 default_erl;
u8 t10_pi;
struct iscsi_portal_group *tpg;
};

Expand All @@ -787,6 +789,7 @@ struct iscsi_np {
void *np_context;
struct iscsit_transport *np_transport;
struct list_head np_list;
struct iscsi_tpg_np *tpg_np;
} ____cacheline_aligned;

struct iscsi_tpg_np {
Expand Down
4 changes: 3 additions & 1 deletion drivers/target/iscsi/iscsi_target_login.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ static int iscsi_login_zero_tsih_s1(
{
struct iscsi_session *sess = NULL;
struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
enum target_prot_op sup_pro_ops;
int ret;

sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL);
Expand Down Expand Up @@ -320,8 +321,9 @@ static int iscsi_login_zero_tsih_s1(
kfree(sess);
return -ENOMEM;
}
sup_pro_ops = conn->conn_transport->iscsit_get_sup_prot_ops(conn);

sess->se_sess = transport_init_session();
sess->se_sess = transport_init_session(sup_pro_ops);
if (IS_ERR(sess->se_sess)) {
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
ISCSI_LOGIN_STATUS_NO_RESOURCES);
Expand Down
21 changes: 21 additions & 0 deletions drivers/target/iscsi/iscsi_target_tpg.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
a->prod_mode_write_protect = TA_PROD_MODE_WRITE_PROTECT;
a->demo_mode_discovery = TA_DEMO_MODE_DISCOVERY;
a->default_erl = TA_DEFAULT_ERL;
a->t10_pi = TA_DEFAULT_T10_PI;
}

int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
Expand Down Expand Up @@ -500,6 +501,7 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
init_completion(&tpg_np->tpg_np_comp);
kref_init(&tpg_np->tpg_np_kref);
tpg_np->tpg_np = np;
np->tpg_np = tpg_np;
tpg_np->tpg = tpg;

spin_lock(&tpg->tpg_np_lock);
Expand Down Expand Up @@ -858,3 +860,22 @@ int iscsit_ta_default_erl(

return 0;
}

int iscsit_ta_t10_pi(
struct iscsi_portal_group *tpg,
u32 flag)
{
struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;

if ((flag != 0) && (flag != 1)) {
pr_err("Illegal value %d\n", flag);
return -EINVAL;
}

a->t10_pi = flag;
pr_debug("iSCSI_TPG[%hu] - T10 Protection information bit:"
" %s\n", tpg->tpgt, (a->t10_pi) ?
"ON" : "OFF");

return 0;
}
1 change: 1 addition & 0 deletions drivers/target/iscsi/iscsi_target_tpg.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ extern int iscsit_ta_demo_mode_write_protect(struct iscsi_portal_group *, u32);
extern int iscsit_ta_prod_mode_write_protect(struct iscsi_portal_group *, u32);
extern int iscsit_ta_demo_mode_discovery(struct iscsi_portal_group *, u32);
extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32);
extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32);

#endif /* ISCSI_TARGET_TPG_H */
Loading

0 comments on commit 141eacc

Please sign in to comment.