Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger: "The highlights this round include: - Add target_alloc_session() w/ callback helper for doing se_session allocation + tag + se_node_acl lookup. (HCH + nab) - Tree-wide fabric driver conversion to use target_alloc_session() - Convert sbp-target to use percpu_ida tag pre-allocation, and TARGET_SCF_ACK_KREF I/O krefs (Chris Boot + nab) - Convert usb-gadget to use percpu_ida tag pre-allocation, and TARGET_SCF_ACK_KREF I/O krefs (Andrzej Pietrasiewicz + nab) - Convert xen-scsiback to use percpu_ida tag pre-allocation, and TARGET_SCF_ACK_KREF I/O krefs (Juergen Gross + nab) - Convert tcm_fc to use TARGET_SCF_ACK_KREF I/O + TMR krefs - Convert ib_srpt to use percpu_ida tag pre-allocation - Add DebugFS node for qla2xxx target sess list (Quinn) - Rework iser-target connection termination (Jenny + Sagi) - Convert iser-target to new CQ API (HCH) - Add pass-through WRITE_SAME support for IBLOCK (Mike Christie) - Introduce data_bitmap for asynchronous access of data area (Sheng Yang + Andy) - Fix target_release_cmd_kref shutdown comp leak (Himanshu Madhani) Also, there is a separate PULL request coming for cxgb4 NIC driver prerequisites for supporting hw iscsi segmentation offload (ISO), that will be the base for a number of v4.7 developments involving iscsi-target hw offloads" * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (36 commits) target: Fix target_release_cmd_kref shutdown comp leak target: Avoid DataIN transfers for non-GOOD SAM status target/user: Report capability of handling out-of-order completions to userspace target/user: Fix size_t format-spec build warning target/user: Don't free expired command when time out target/user: Introduce data_bitmap, replace data_length/data_head/data_tail target/user: Free data ring in unified function target/user: Use iovec[] to describe continuous area target: Remove enum transport_lunflags_table target/iblock: pass WRITE_SAME to device if possible iser-target: Kill the ->isert_cmd back pointer in struct iser_tx_desc iser-target: Kill struct isert_rdma_wr iser-target: Convert to new CQ API iser-target: Split and properly type the login buffer iser-target: Remove ISER_RECV_DATA_SEG_LEN iser-target: Remove impossible condition from isert_wait_conn iser-target: Remove redundant wait in release_conn iser-target: Rework connection termination iser-target: Separate flows for np listeners and connections cma events iser-target: Add new state ISER_CONN_BOUND to isert_conn ...
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -36,9 +36,7 @@
|
||||
/* Constant PDU lengths calculations */
|
||||
#define ISER_HEADERS_LEN (sizeof(struct iser_ctrl) + \
|
||||
sizeof(struct iscsi_hdr))
|
||||
#define ISER_RECV_DATA_SEG_LEN 8192
|
||||
#define ISER_RX_PAYLOAD_SIZE (ISER_HEADERS_LEN + ISER_RECV_DATA_SEG_LEN)
|
||||
#define ISER_RX_LOGIN_SIZE (ISER_HEADERS_LEN + ISCSI_DEF_MAX_RECV_SEG_LEN)
|
||||
#define ISER_RX_PAYLOAD_SIZE (ISER_HEADERS_LEN + ISCSI_DEF_MAX_RECV_SEG_LEN)
|
||||
|
||||
/* QP settings */
|
||||
/* Maximal bounds on received asynchronous PDUs */
|
||||
@@ -62,12 +60,11 @@
|
||||
ISERT_MAX_TX_MISC_PDUS + \
|
||||
ISERT_MAX_RX_MISC_PDUS)
|
||||
|
||||
#define ISER_RX_PAD_SIZE (ISER_RECV_DATA_SEG_LEN + 4096 - \
|
||||
(ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge)))
|
||||
#define ISER_RX_PAD_SIZE (ISCSI_DEF_MAX_RECV_SEG_LEN + 4096 - \
|
||||
(ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge) + \
|
||||
sizeof(struct ib_cqe)))
|
||||
|
||||
#define ISCSI_ISER_SG_TABLESIZE 256
|
||||
#define ISER_FASTREG_LI_WRID 0xffffffffffffffffULL
|
||||
#define ISER_BEACON_WRID 0xfffffffffffffffeULL
|
||||
|
||||
enum isert_desc_type {
|
||||
ISCSI_TX_CONTROL,
|
||||
@@ -84,6 +81,7 @@ enum iser_ib_op_code {
|
||||
enum iser_conn_state {
|
||||
ISER_CONN_INIT,
|
||||
ISER_CONN_UP,
|
||||
ISER_CONN_BOUND,
|
||||
ISER_CONN_FULL_FEATURE,
|
||||
ISER_CONN_TERMINATING,
|
||||
ISER_CONN_DOWN,
|
||||
@@ -92,23 +90,35 @@ enum iser_conn_state {
|
||||
struct iser_rx_desc {
|
||||
struct iser_ctrl iser_header;
|
||||
struct iscsi_hdr iscsi_header;
|
||||
char data[ISER_RECV_DATA_SEG_LEN];
|
||||
char data[ISCSI_DEF_MAX_RECV_SEG_LEN];
|
||||
u64 dma_addr;
|
||||
struct ib_sge rx_sg;
|
||||
struct ib_cqe rx_cqe;
|
||||
char pad[ISER_RX_PAD_SIZE];
|
||||
} __packed;
|
||||
|
||||
static inline struct iser_rx_desc *cqe_to_rx_desc(struct ib_cqe *cqe)
|
||||
{
|
||||
return container_of(cqe, struct iser_rx_desc, rx_cqe);
|
||||
}
|
||||
|
||||
struct iser_tx_desc {
|
||||
struct iser_ctrl iser_header;
|
||||
struct iscsi_hdr iscsi_header;
|
||||
enum isert_desc_type type;
|
||||
u64 dma_addr;
|
||||
struct ib_sge tx_sg[2];
|
||||
struct ib_cqe tx_cqe;
|
||||
int num_sge;
|
||||
struct isert_cmd *isert_cmd;
|
||||
struct ib_send_wr send_wr;
|
||||
} __packed;
|
||||
|
||||
static inline struct iser_tx_desc *cqe_to_tx_desc(struct ib_cqe *cqe)
|
||||
{
|
||||
return container_of(cqe, struct iser_tx_desc, tx_cqe);
|
||||
}
|
||||
|
||||
|
||||
enum isert_indicator {
|
||||
ISERT_PROTECTED = 1 << 0,
|
||||
ISERT_DATA_KEY_VALID = 1 << 1,
|
||||
@@ -144,20 +154,6 @@ enum {
|
||||
SIG = 2,
|
||||
};
|
||||
|
||||
struct isert_rdma_wr {
|
||||
struct isert_cmd *isert_cmd;
|
||||
enum iser_ib_op_code iser_ib_op;
|
||||
struct ib_sge *ib_sge;
|
||||
struct ib_sge s_ib_sge;
|
||||
int rdma_wr_num;
|
||||
struct ib_rdma_wr *rdma_wr;
|
||||
struct ib_rdma_wr s_rdma_wr;
|
||||
struct ib_sge ib_sg[3];
|
||||
struct isert_data_buf data;
|
||||
struct isert_data_buf prot;
|
||||
struct fast_reg_descriptor *fr_desc;
|
||||
};
|
||||
|
||||
struct isert_cmd {
|
||||
uint32_t read_stag;
|
||||
uint32_t write_stag;
|
||||
@@ -170,22 +166,34 @@ struct isert_cmd {
|
||||
struct iscsi_cmd *iscsi_cmd;
|
||||
struct iser_tx_desc tx_desc;
|
||||
struct iser_rx_desc *rx_desc;
|
||||
struct isert_rdma_wr rdma_wr;
|
||||
enum iser_ib_op_code iser_ib_op;
|
||||
struct ib_sge *ib_sge;
|
||||
struct ib_sge s_ib_sge;
|
||||
int rdma_wr_num;
|
||||
struct ib_rdma_wr *rdma_wr;
|
||||
struct ib_rdma_wr s_rdma_wr;
|
||||
struct ib_sge ib_sg[3];
|
||||
struct isert_data_buf data;
|
||||
struct isert_data_buf prot;
|
||||
struct fast_reg_descriptor *fr_desc;
|
||||
struct work_struct comp_work;
|
||||
struct scatterlist sg;
|
||||
};
|
||||
|
||||
static inline struct isert_cmd *tx_desc_to_cmd(struct iser_tx_desc *desc)
|
||||
{
|
||||
return container_of(desc, struct isert_cmd, tx_desc);
|
||||
}
|
||||
|
||||
struct isert_device;
|
||||
|
||||
struct isert_conn {
|
||||
enum iser_conn_state state;
|
||||
int post_recv_buf_count;
|
||||
u32 responder_resources;
|
||||
u32 initiator_depth;
|
||||
bool pi_support;
|
||||
u32 max_sge;
|
||||
char *login_buf;
|
||||
char *login_req_buf;
|
||||
struct iser_rx_desc *login_req_buf;
|
||||
char *login_rsp_buf;
|
||||
u64 login_req_dma;
|
||||
int login_req_len;
|
||||
@@ -201,7 +209,6 @@ struct isert_conn {
|
||||
struct ib_qp *qp;
|
||||
struct isert_device *device;
|
||||
struct mutex mutex;
|
||||
struct completion wait;
|
||||
struct completion wait_comp_err;
|
||||
struct kref kref;
|
||||
struct list_head fr_pool;
|
||||
@@ -221,17 +228,13 @@ struct isert_conn {
|
||||
*
|
||||
* @device: pointer to device handle
|
||||
* @cq: completion queue
|
||||
* @wcs: work completion array
|
||||
* @active_qps: Number of active QPs attached
|
||||
* to completion context
|
||||
* @work: completion work handle
|
||||
*/
|
||||
struct isert_comp {
|
||||
struct isert_device *device;
|
||||
struct ib_cq *cq;
|
||||
struct ib_wc wcs[16];
|
||||
int active_qps;
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
struct isert_device {
|
||||
@@ -243,9 +246,8 @@ struct isert_device {
|
||||
struct isert_comp *comps;
|
||||
int comps_used;
|
||||
struct list_head dev_node;
|
||||
int (*reg_rdma_mem)(struct iscsi_conn *conn,
|
||||
struct iscsi_cmd *cmd,
|
||||
struct isert_rdma_wr *wr);
|
||||
int (*reg_rdma_mem)(struct isert_cmd *isert_cmd,
|
||||
struct iscsi_conn *conn);
|
||||
void (*unreg_rdma_mem)(struct isert_cmd *isert_cmd,
|
||||
struct isert_conn *isert_conn);
|
||||
};
|
||||
|
@@ -1264,40 +1264,26 @@ free_mem:
|
||||
*/
|
||||
static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch)
|
||||
{
|
||||
struct se_session *se_sess;
|
||||
struct srpt_send_ioctx *ioctx;
|
||||
unsigned long flags;
|
||||
int tag;
|
||||
|
||||
BUG_ON(!ch);
|
||||
se_sess = ch->sess;
|
||||
|
||||
ioctx = NULL;
|
||||
spin_lock_irqsave(&ch->spinlock, flags);
|
||||
if (!list_empty(&ch->free_list)) {
|
||||
ioctx = list_first_entry(&ch->free_list,
|
||||
struct srpt_send_ioctx, free_list);
|
||||
list_del(&ioctx->free_list);
|
||||
tag = percpu_ida_alloc(&se_sess->sess_tag_pool, TASK_RUNNING);
|
||||
if (tag < 0) {
|
||||
pr_err("Unable to obtain tag for srpt_send_ioctx\n");
|
||||
return NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&ch->spinlock, flags);
|
||||
|
||||
if (!ioctx)
|
||||
return ioctx;
|
||||
|
||||
BUG_ON(ioctx->ch != ch);
|
||||
ioctx = &((struct srpt_send_ioctx *)se_sess->sess_cmd_map)[tag];
|
||||
memset(ioctx, 0, sizeof(struct srpt_send_ioctx));
|
||||
ioctx->ch = ch;
|
||||
spin_lock_init(&ioctx->spinlock);
|
||||
ioctx->state = SRPT_STATE_NEW;
|
||||
ioctx->n_rbuf = 0;
|
||||
ioctx->rbufs = NULL;
|
||||
ioctx->n_rdma = 0;
|
||||
ioctx->n_rdma_wrs = 0;
|
||||
ioctx->rdma_wrs = NULL;
|
||||
ioctx->mapped_sg_count = 0;
|
||||
init_completion(&ioctx->tx_done);
|
||||
ioctx->queue_status_only = false;
|
||||
/*
|
||||
* transport_init_se_cmd() does not initialize all fields, so do it
|
||||
* here.
|
||||
*/
|
||||
memset(&ioctx->cmd, 0, sizeof(ioctx->cmd));
|
||||
memset(&ioctx->sense_data, 0, sizeof(ioctx->sense_data));
|
||||
|
||||
ioctx->cmd.map_tag = tag;
|
||||
|
||||
return ioctx;
|
||||
}
|
||||
@@ -2034,9 +2020,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
|
||||
struct srp_login_rej *rej;
|
||||
struct ib_cm_rep_param *rep_param;
|
||||
struct srpt_rdma_ch *ch, *tmp_ch;
|
||||
struct se_node_acl *se_acl;
|
||||
u32 it_iu_len;
|
||||
int i, ret = 0;
|
||||
int ret = 0;
|
||||
unsigned char *p;
|
||||
|
||||
WARN_ON_ONCE(irqs_disabled());
|
||||
@@ -2158,12 +2143,6 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
|
||||
if (!ch->ioctx_ring)
|
||||
goto free_ch;
|
||||
|
||||
INIT_LIST_HEAD(&ch->free_list);
|
||||
for (i = 0; i < ch->rq_size; i++) {
|
||||
ch->ioctx_ring[i]->ch = ch;
|
||||
list_add_tail(&ch->ioctx_ring[i]->free_list, &ch->free_list);
|
||||
}
|
||||
|
||||
ret = srpt_create_ch_ib(ch);
|
||||
if (ret) {
|
||||
rej->reason = cpu_to_be32(
|
||||
@@ -2193,19 +2172,13 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
|
||||
pr_debug("registering session %s\n", ch->sess_name);
|
||||
p = &ch->sess_name[0];
|
||||
|
||||
ch->sess = transport_init_session(TARGET_PROT_NORMAL);
|
||||
if (IS_ERR(ch->sess)) {
|
||||
rej->reason = cpu_to_be32(
|
||||
SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);
|
||||
pr_debug("Failed to create session\n");
|
||||
goto destroy_ib;
|
||||
}
|
||||
|
||||
try_again:
|
||||
se_acl = core_tpg_get_initiator_node_acl(&sport->port_tpg_1, p);
|
||||
if (!se_acl) {
|
||||
ch->sess = target_alloc_session(&sport->port_tpg_1, ch->rq_size,
|
||||
sizeof(struct srpt_send_ioctx),
|
||||
TARGET_PROT_NORMAL, p, ch, NULL);
|
||||
if (IS_ERR(ch->sess)) {
|
||||
pr_info("Rejected login because no ACL has been"
|
||||
" configured yet for initiator %s.\n", ch->sess_name);
|
||||
" configured yet for initiator %s.\n", p);
|
||||
/*
|
||||
* XXX: Hack to retry of ch->i_port_id without leading '0x'
|
||||
*/
|
||||
@@ -2213,14 +2186,11 @@ try_again:
|
||||
p += 2;
|
||||
goto try_again;
|
||||
}
|
||||
rej->reason = cpu_to_be32(
|
||||
rej->reason = cpu_to_be32((PTR_ERR(ch->sess) == -ENOMEM) ?
|
||||
SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES :
|
||||
SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED);
|
||||
transport_free_session(ch->sess);
|
||||
goto destroy_ib;
|
||||
}
|
||||
ch->sess->se_node_acl = se_acl;
|
||||
|
||||
transport_register_session(&sport->port_tpg_1, se_acl, ch->sess, ch);
|
||||
|
||||
pr_debug("Establish connection sess=%p name=%s cm_id=%p\n", ch->sess,
|
||||
ch->sess_name, ch->cm_id);
|
||||
@@ -2911,7 +2881,7 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
|
||||
struct srpt_send_ioctx *ioctx = container_of(se_cmd,
|
||||
struct srpt_send_ioctx, cmd);
|
||||
struct srpt_rdma_ch *ch = ioctx->ch;
|
||||
unsigned long flags;
|
||||
struct se_session *se_sess = ch->sess;
|
||||
|
||||
WARN_ON(ioctx->state != SRPT_STATE_DONE);
|
||||
WARN_ON(ioctx->mapped_sg_count != 0);
|
||||
@@ -2922,9 +2892,7 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
|
||||
ioctx->n_rbuf = 0;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ch->spinlock, flags);
|
||||
list_add(&ioctx->free_list, &ch->free_list);
|
||||
spin_unlock_irqrestore(&ch->spinlock, flags);
|
||||
percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -179,7 +179,6 @@ struct srpt_recv_ioctx {
|
||||
* struct srpt_send_ioctx - SRPT send I/O context.
|
||||
* @ioctx: See above.
|
||||
* @ch: Channel pointer.
|
||||
* @free_list: Node in srpt_rdma_ch.free_list.
|
||||
* @n_rbuf: Number of data buffers in the received SRP command.
|
||||
* @rbufs: Pointer to SRP data buffer array.
|
||||
* @single_rbuf: SRP data buffer if the command has only a single buffer.
|
||||
@@ -202,7 +201,6 @@ struct srpt_send_ioctx {
|
||||
struct srp_direct_buf *rbufs;
|
||||
struct srp_direct_buf single_rbuf;
|
||||
struct scatterlist *sg;
|
||||
struct list_head free_list;
|
||||
spinlock_t spinlock;
|
||||
enum srpt_command_state state;
|
||||
struct se_cmd cmd;
|
||||
|
Reference in New Issue
Block a user