iser-target: Fix NULL dereference in SW mode DIF
Fallback to software mode DIF if HCA does not support PI (without crashing obviously). It is still possible to run with backend protection and an unprotected frontend, so looking at the command prot_op is not enough. Check device PI capability on a per-IO basis (isert_prot_cmd inline static) to determine if we need to handle protection information. Trace: BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 IP: [<ffffffffa037f8b1>] isert_reg_sig_mr+0x351/0x3b0 [ib_isert] Call Trace: [<ffffffff812b003a>] ? swiotlb_map_sg_attrs+0x7a/0x130 [<ffffffffa038184d>] isert_reg_rdma+0x2fd/0x370 [ib_isert] [<ffffffff8108f2ec>] ? idle_balance+0x6c/0x2c0 [<ffffffffa0382b68>] isert_put_datain+0x68/0x210 [ib_isert] [<ffffffffa02acf5b>] lio_queue_data_in+0x2b/0x30 [iscsi_target_mod] [<ffffffffa02306eb>] target_complete_ok_work+0x21b/0x310 [target_core_mod] [<ffffffff8106ece2>] process_one_work+0x182/0x3b0 [<ffffffff8106fda0>] worker_thread+0x120/0x3c0 [<ffffffff8106fc80>] ? maybe_create_worker+0x190/0x190 [<ffffffff8107594e>] kthread+0xce/0xf0 [<ffffffff81075880>] ? kthread_freezable_should_stop+0x70/0x70 [<ffffffff8159a22c>] ret_from_fork+0x7c/0xb0 [<ffffffff81075880>] ? kthread_freezable_should_stop+0x70/0x70 Reported-by: Slava Shwartsman <valyushash@gmail.com> Signed-off-by: Sagi Grimberg <sagig@mellanox.com> Cc: <stable@vger.kernel.org> # v3.14+ Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
570db170f3
commit
302cc7c3ca
|
@ -61,6 +61,14 @@ static int
|
||||||
isert_rdma_accept(struct isert_conn *isert_conn);
|
isert_rdma_accept(struct isert_conn *isert_conn);
|
||||||
struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
|
struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd)
|
||||||
|
{
|
||||||
|
return (conn->conn_device->pi_capable &&
|
||||||
|
cmd->prot_op != TARGET_PROT_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
isert_qp_event_callback(struct ib_event *e, void *context)
|
isert_qp_event_callback(struct ib_event *e, void *context)
|
||||||
{
|
{
|
||||||
|
@ -2919,8 +2927,7 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (wr->data.dma_nents != 1 ||
|
if (wr->data.dma_nents != 1 || isert_prot_cmd(isert_conn, se_cmd)) {
|
||||||
se_cmd->prot_op != TARGET_PROT_NORMAL) {
|
|
||||||
spin_lock_irqsave(&isert_conn->conn_lock, flags);
|
spin_lock_irqsave(&isert_conn->conn_lock, flags);
|
||||||
fr_desc = list_first_entry(&isert_conn->conn_fr_pool,
|
fr_desc = list_first_entry(&isert_conn->conn_fr_pool,
|
||||||
struct fast_reg_descriptor, list);
|
struct fast_reg_descriptor, list);
|
||||||
|
@ -2934,7 +2941,7 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto unmap_cmd;
|
goto unmap_cmd;
|
||||||
|
|
||||||
if (se_cmd->prot_op != TARGET_PROT_NORMAL) {
|
if (isert_prot_cmd(isert_conn, se_cmd)) {
|
||||||
ret = isert_handle_prot_cmd(isert_conn, isert_cmd, wr);
|
ret = isert_handle_prot_cmd(isert_conn, isert_cmd, wr);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto unmap_cmd;
|
goto unmap_cmd;
|
||||||
|
@ -2959,7 +2966,7 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||||
send_wr->opcode = IB_WR_RDMA_WRITE;
|
send_wr->opcode = IB_WR_RDMA_WRITE;
|
||||||
send_wr->wr.rdma.remote_addr = isert_cmd->read_va;
|
send_wr->wr.rdma.remote_addr = isert_cmd->read_va;
|
||||||
send_wr->wr.rdma.rkey = isert_cmd->read_stag;
|
send_wr->wr.rdma.rkey = isert_cmd->read_stag;
|
||||||
send_wr->send_flags = se_cmd->prot_op == TARGET_PROT_NORMAL ?
|
send_wr->send_flags = !isert_prot_cmd(isert_conn, se_cmd) ?
|
||||||
0 : IB_SEND_SIGNALED;
|
0 : IB_SEND_SIGNALED;
|
||||||
} else {
|
} else {
|
||||||
send_wr->opcode = IB_WR_RDMA_READ;
|
send_wr->opcode = IB_WR_RDMA_READ;
|
||||||
|
@ -3001,7 +3008,7 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (se_cmd->prot_op == TARGET_PROT_NORMAL) {
|
if (!isert_prot_cmd(isert_conn, se_cmd)) {
|
||||||
/*
|
/*
|
||||||
* Build isert_conn->tx_desc for iSCSI response PDU and attach
|
* Build isert_conn->tx_desc for iSCSI response PDU and attach
|
||||||
*/
|
*/
|
||||||
|
@ -3024,7 +3031,7 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
|
||||||
atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count);
|
atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (se_cmd->prot_op == TARGET_PROT_NORMAL)
|
if (!isert_prot_cmd(isert_conn, se_cmd))
|
||||||
pr_debug("Cmd: %p posted RDMA_WRITE + Response for iSER Data "
|
pr_debug("Cmd: %p posted RDMA_WRITE + Response for iSER Data "
|
||||||
"READ\n", isert_cmd);
|
"READ\n", isert_cmd);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue