Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c2187f0 authored by Roland Dreier's avatar Roland Dreier
Browse files

Merge branch 'iser' into for-next

parents 7f168162 88ec4157
Loading
Loading
Loading
Loading
+32 −15
Original line number Original line Diff line number Diff line
@@ -128,6 +128,28 @@ static int iscsi_iser_pdu_alloc(struct iscsi_task *task, uint8_t opcode)
	return 0;
	return 0;
}
}


int iser_initialize_task_headers(struct iscsi_task *task,
						struct iser_tx_desc *tx_desc)
{
	struct iscsi_iser_conn *iser_conn = task->conn->dd_data;
	struct iser_device     *device    = iser_conn->ib_conn->device;
	struct iscsi_iser_task *iser_task = task->dd_data;
	u64 dma_addr;

	dma_addr = ib_dma_map_single(device->ib_device, (void *)tx_desc,
				ISER_HEADERS_LEN, DMA_TO_DEVICE);
	if (ib_dma_mapping_error(device->ib_device, dma_addr))
		return -ENOMEM;

	tx_desc->dma_addr = dma_addr;
	tx_desc->tx_sg[0].addr   = tx_desc->dma_addr;
	tx_desc->tx_sg[0].length = ISER_HEADERS_LEN;
	tx_desc->tx_sg[0].lkey   = device->mr->lkey;

	iser_task->headers_initialized	= 1;
	iser_task->iser_conn		= iser_conn;
	return 0;
}
/**
/**
 * iscsi_iser_task_init - Initialize task
 * iscsi_iser_task_init - Initialize task
 * @task: iscsi task
 * @task: iscsi task
@@ -137,17 +159,17 @@ static int iscsi_iser_pdu_alloc(struct iscsi_task *task, uint8_t opcode)
static int
static int
iscsi_iser_task_init(struct iscsi_task *task)
iscsi_iser_task_init(struct iscsi_task *task)
{
{
	struct iscsi_iser_conn *iser_conn  = task->conn->dd_data;
	struct iscsi_iser_task *iser_task = task->dd_data;
	struct iscsi_iser_task *iser_task = task->dd_data;


	if (!iser_task->headers_initialized)
		if (iser_initialize_task_headers(task, &iser_task->desc))
			return -ENOMEM;

	/* mgmt task */
	/* mgmt task */
	if (!task->sc) {
	if (!task->sc)
		iser_task->desc.data = task->data;
		return 0;
		return 0;
	}


	iser_task->command_sent = 0;
	iser_task->command_sent = 0;
	iser_task->iser_conn    = iser_conn;
	iser_task_rdma_init(iser_task);
	iser_task_rdma_init(iser_task);
	return 0;
	return 0;
}
}
@@ -168,7 +190,7 @@ iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task)
{
{
	int error = 0;
	int error = 0;


	iser_dbg("task deq [cid %d itt 0x%x]\n", conn->id, task->itt);
	iser_dbg("mtask xmit [cid %d itt 0x%x]\n", conn->id, task->itt);


	error = iser_send_control(conn, task);
	error = iser_send_control(conn, task);


@@ -178,9 +200,6 @@ iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task)
	 * - if yes, the task is recycled at iscsi_complete_pdu
	 * - if yes, the task is recycled at iscsi_complete_pdu
	 * - if no,  the task is recycled at iser_snd_completion
	 * - if no,  the task is recycled at iser_snd_completion
	 */
	 */
	if (error && error != -ENOBUFS)
		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);

	return error;
	return error;
}
}


@@ -232,7 +251,7 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
			   task->imm_count, task->unsol_r2t.data_length);
			   task->imm_count, task->unsol_r2t.data_length);
	}
	}


	iser_dbg("task deq [cid %d itt 0x%x]\n",
	iser_dbg("ctask xmit [cid %d itt 0x%x]\n",
		   conn->id, task->itt);
		   conn->id, task->itt);


	/* Send the cmd PDU */
	/* Send the cmd PDU */
@@ -248,8 +267,6 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
		error = iscsi_iser_task_xmit_unsol_data(conn, task);
		error = iscsi_iser_task_xmit_unsol_data(conn, task);


 iscsi_iser_task_xmit_exit:
 iscsi_iser_task_xmit_exit:
	if (error && error != -ENOBUFS)
		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
	return error;
	return error;
}
}


@@ -283,7 +300,7 @@ iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
	 * due to issues with the login code re iser sematics
	 * due to issues with the login code re iser sematics
	 * this not set in iscsi_conn_setup - FIXME
	 * this not set in iscsi_conn_setup - FIXME
	 */
	 */
	conn->max_recv_dlength = 128;
	conn->max_recv_dlength = ISER_RECV_DATA_SEG_LEN;


	iser_conn = conn->dd_data;
	iser_conn = conn->dd_data;
	conn->dd_data = iser_conn;
	conn->dd_data = iser_conn;
@@ -401,7 +418,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
	struct Scsi_Host *shost;
	struct Scsi_Host *shost;
	struct iser_conn *ib_conn;
	struct iser_conn *ib_conn;


	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, 1);
	shost = iscsi_host_alloc(&iscsi_iser_sht, 0, 0);
	if (!shost)
	if (!shost)
		return NULL;
		return NULL;
	shost->transportt = iscsi_iser_scsi_transport;
	shost->transportt = iscsi_iser_scsi_transport;
@@ -675,7 +692,7 @@ static int __init iser_init(void)
	memset(&ig, 0, sizeof(struct iser_global));
	memset(&ig, 0, sizeof(struct iser_global));


	ig.desc_cache = kmem_cache_create("iser_descriptors",
	ig.desc_cache = kmem_cache_create("iser_descriptors",
					  sizeof (struct iser_desc),
					  sizeof(struct iser_tx_desc),
					  0, SLAB_HWCACHE_ALIGN,
					  0, SLAB_HWCACHE_ALIGN,
					  NULL);
					  NULL);
	if (ig.desc_cache == NULL)
	if (ig.desc_cache == NULL)
+47 −50
Original line number Original line Diff line number Diff line
@@ -102,9 +102,9 @@
#define ISER_MAX_TX_MISC_PDUS		6 /* NOOP_OUT(2), TEXT(1),         *
#define ISER_MAX_TX_MISC_PDUS		6 /* NOOP_OUT(2), TEXT(1),         *
					   * SCSI_TMFUNC(2), LOGOUT(1) */
					   * SCSI_TMFUNC(2), LOGOUT(1) */


#define ISER_QP_MAX_RECV_DTOS		(ISCSI_DEF_XMIT_CMDS_MAX + \
#define ISER_QP_MAX_RECV_DTOS		(ISCSI_DEF_XMIT_CMDS_MAX)
					ISER_MAX_RX_MISC_PDUS    +  \

					ISER_MAX_TX_MISC_PDUS)
#define ISER_MIN_POSTED_RX		(ISCSI_DEF_XMIT_CMDS_MAX >> 2)


/* the max TX (send) WR supported by the iSER QP is defined by                 *
/* the max TX (send) WR supported by the iSER QP is defined by                 *
 * max_send_wr = T * (1 + D) + C ; D is how many inflight dataouts we expect   *
 * max_send_wr = T * (1 + D) + C ; D is how many inflight dataouts we expect   *
@@ -132,6 +132,12 @@ struct iser_hdr {
	__be64  read_va;
	__be64  read_va;
} __attribute__((packed));
} __attribute__((packed));


/* Constant PDU lengths calculations */
#define ISER_HEADERS_LEN  (sizeof(struct iser_hdr) + sizeof(struct iscsi_hdr))

#define ISER_RECV_DATA_SEG_LEN	128
#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)


/* Length of an object name string */
/* Length of an object name string */
#define ISER_OBJECT_NAME_SIZE		    64
#define ISER_OBJECT_NAME_SIZE		    64
@@ -187,51 +193,43 @@ struct iser_regd_buf {
	struct iser_mem_reg     reg;        /* memory registration info        */
	struct iser_mem_reg     reg;        /* memory registration info        */
	void                    *virt_addr;
	void                    *virt_addr;
	struct iser_device      *device;    /* device->device for dma_unmap    */
	struct iser_device      *device;    /* device->device for dma_unmap    */
	u64                     dma_addr;   /* if non zero, addr for dma_unmap */
	enum dma_data_direction direction;  /* direction for dma_unmap	       */
	enum dma_data_direction direction;  /* direction for dma_unmap	       */
	unsigned int            data_size;
	unsigned int            data_size;
	atomic_t                ref_count;  /* refcount, freed when dec to 0   */
};

#define MAX_REGD_BUF_VECTOR_LEN	2

struct iser_dto {
	struct iscsi_iser_task *task;
	struct iser_conn *ib_conn;
	int                        notify_enable;

	/* vector of registered buffers */
	unsigned int               regd_vector_len;
	struct iser_regd_buf       *regd[MAX_REGD_BUF_VECTOR_LEN];

	/* offset into the registered buffer may be specified */
	unsigned int               offset[MAX_REGD_BUF_VECTOR_LEN];

	/* a smaller size may be specified, if 0, then full size is used */
	unsigned int               used_sz[MAX_REGD_BUF_VECTOR_LEN];
};
};


enum iser_desc_type {
enum iser_desc_type {
	ISCSI_RX,
	ISCSI_TX_CONTROL ,
	ISCSI_TX_CONTROL ,
	ISCSI_TX_SCSI_COMMAND,
	ISCSI_TX_SCSI_COMMAND,
	ISCSI_TX_DATAOUT
	ISCSI_TX_DATAOUT
};
};


struct iser_desc {
struct iser_tx_desc {
	struct iser_hdr              iser_header;
	struct iser_hdr              iser_header;
	struct iscsi_hdr             iscsi_header;
	struct iscsi_hdr             iscsi_header;
	struct iser_regd_buf         hdr_regd_buf;
	void                         *data;         /* used by RX & TX_CONTROL */
	struct iser_regd_buf         data_regd_buf; /* used by RX & TX_CONTROL */
	enum   iser_desc_type        type;
	enum   iser_desc_type        type;
	struct iser_dto              dto;
	u64		             dma_addr;
	/* sg[0] points to iser/iscsi headers, sg[1] optionally points to either
	of immediate data, unsolicited data-out or control (login,text) */
	struct ib_sge		     tx_sg[2];
	int                          num_sge;
};
};


#define ISER_RX_PAD_SIZE	(256 - (ISER_RX_PAYLOAD_SIZE + \
					sizeof(u64) + sizeof(struct ib_sge)))
struct iser_rx_desc {
	struct iser_hdr              iser_header;
	struct iscsi_hdr             iscsi_header;
	char		             data[ISER_RECV_DATA_SEG_LEN];
	u64		             dma_addr;
	struct ib_sge		     rx_sg;
	char		             pad[ISER_RX_PAD_SIZE];
} __attribute__((packed));

struct iser_device {
struct iser_device {
	struct ib_device             *ib_device;
	struct ib_device             *ib_device;
	struct ib_pd	             *pd;
	struct ib_pd	             *pd;
	struct ib_cq	             *cq;
	struct ib_cq	             *rx_cq;
	struct ib_cq	             *tx_cq;
	struct ib_mr	             *mr;
	struct ib_mr	             *mr;
	struct tasklet_struct	     cq_tasklet;
	struct tasklet_struct	     cq_tasklet;
	struct list_head             ig_list; /* entry in ig devices list */
	struct list_head             ig_list; /* entry in ig devices list */
@@ -250,15 +248,18 @@ struct iser_conn {
	struct ib_fmr_pool           *fmr_pool;     /* pool of IB FMRs         */
	struct ib_fmr_pool           *fmr_pool;     /* pool of IB FMRs         */
	int                          disc_evt_flag; /* disconn event delivered */
	int                          disc_evt_flag; /* disconn event delivered */
	wait_queue_head_t	     wait;          /* waitq for conn/disconn  */
	wait_queue_head_t	     wait;          /* waitq for conn/disconn  */
	atomic_t                     post_recv_buf_count; /* posted rx count   */
	int                          post_recv_buf_count; /* posted rx count  */
	atomic_t                     post_send_buf_count; /* posted tx count   */
	atomic_t                     post_send_buf_count; /* posted tx count   */
	atomic_t                     unexpected_pdu_count;/* count of received *
							   * unexpected pdus   *
							   * not yet retired   */
	char 			     name[ISER_OBJECT_NAME_SIZE];
	char 			     name[ISER_OBJECT_NAME_SIZE];
	struct iser_page_vec         *page_vec;     /* represents SG to fmr maps*
	struct iser_page_vec         *page_vec;     /* represents SG to fmr maps*
						     * maps serialized as tx is*/
						     * maps serialized as tx is*/
	struct list_head	     conn_list;       /* entry in ig conn list */
	struct list_head	     conn_list;       /* entry in ig conn list */

	char  			     *login_buf;
	u64 			     login_dma;
	unsigned int 		     rx_desc_head;
	struct iser_rx_desc	     *rx_descs;
	struct ib_recv_wr	     rx_wr[ISER_MIN_POSTED_RX];
};
};


struct iscsi_iser_conn {
struct iscsi_iser_conn {
@@ -267,7 +268,7 @@ struct iscsi_iser_conn {
};
};


struct iscsi_iser_task {
struct iscsi_iser_task {
	struct iser_desc             desc;
	struct iser_tx_desc          desc;
	struct iscsi_iser_conn	     *iser_conn;
	struct iscsi_iser_conn	     *iser_conn;
	enum iser_task_status 	     status;
	enum iser_task_status 	     status;
	int                          command_sent;  /* set if command  sent  */
	int                          command_sent;  /* set if command  sent  */
@@ -275,6 +276,7 @@ struct iscsi_iser_task {
	struct iser_regd_buf         rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */
	struct iser_regd_buf         rdma_regd[ISER_DIRS_NUM];/* regd rdma buf */
	struct iser_data_buf         data[ISER_DIRS_NUM];     /* orig. data des*/
	struct iser_data_buf         data[ISER_DIRS_NUM];     /* orig. data des*/
	struct iser_data_buf         data_copy[ISER_DIRS_NUM];/* contig. copy  */
	struct iser_data_buf         data_copy[ISER_DIRS_NUM];/* contig. copy  */
	int                          headers_initialized;
};
};


struct iser_page_vec {
struct iser_page_vec {
@@ -322,22 +324,17 @@ void iser_conn_put(struct iser_conn *ib_conn);


void iser_conn_terminate(struct iser_conn *ib_conn);
void iser_conn_terminate(struct iser_conn *ib_conn);


void iser_rcv_completion(struct iser_desc *desc,
void iser_rcv_completion(struct iser_rx_desc *desc,
			 unsigned long    dto_xfer_len);
			 unsigned long    dto_xfer_len,
			struct iser_conn *ib_conn);


void iser_snd_completion(struct iser_desc *desc);
void iser_snd_completion(struct iser_tx_desc *desc, struct iser_conn *ib_conn);


void iser_task_rdma_init(struct iscsi_iser_task *task);
void iser_task_rdma_init(struct iscsi_iser_task *task);


void iser_task_rdma_finalize(struct iscsi_iser_task *task);
void iser_task_rdma_finalize(struct iscsi_iser_task *task);


void iser_dto_buffs_release(struct iser_dto *dto);
void iser_free_rx_descriptors(struct iser_conn *ib_conn);

int  iser_regd_buff_release(struct iser_regd_buf *regd_buf);

void iser_reg_single(struct iser_device      *device,
		     struct iser_regd_buf    *regd_buf,
		     enum dma_data_direction direction);


void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task,
void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *task,
				     enum iser_data_dir         cmd_dir);
				     enum iser_data_dir         cmd_dir);
@@ -356,11 +353,9 @@ int iser_reg_page_vec(struct iser_conn *ib_conn,


void iser_unreg_mem(struct iser_mem_reg *mem_reg);
void iser_unreg_mem(struct iser_mem_reg *mem_reg);


int  iser_post_recv(struct iser_desc *rx_desc);
int  iser_post_recvl(struct iser_conn *ib_conn);
int  iser_post_send(struct iser_desc *tx_desc);
int  iser_post_recvm(struct iser_conn *ib_conn, int count);

int  iser_post_send(struct iser_conn *ib_conn, struct iser_tx_desc *tx_desc);
int iser_conn_state_comp(struct iser_conn *ib_conn,
			 enum iser_ib_conn_state comp);


int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
			    struct iser_data_buf       *data,
			    struct iser_data_buf       *data,
@@ -368,4 +363,6 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
			    enum   dma_data_direction  dma_dir);
			    enum   dma_data_direction  dma_dir);


void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
int  iser_initialize_task_headers(struct iscsi_task *task,
			struct iser_tx_desc *tx_desc);
#endif
#endif