* [PATCH 0/8] ib/iser: major face lift of the data path code
@ 2010-02-03 15:30 Or Gerlitz
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
0 siblings, 1 reply; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:30 UTC (permalink / raw)
To: Roland Dreier
Cc: linux-rdma, Mike Christie, open-iscsi-/JYPxA39Uh5TLH3MbocFFw
The following patch set removes some in efficiencies in the iser data path
through simplification and reducing the amount of code, using less atomic
operations, avoiding TX interrupts, moving to iscsi passthrough mode,
etc. I did my best to build it as a sequence of patches and not as one
big re-write, to allow for better debugging (e.g bisection) and tuning.
Or.
[PATCH 01/9] ib/iser: revert commit bba7ebb "avoid recv buffer exhaustion"
[PATCH 02/9] ib/iser: new recv buffer posting logic
[PATCH 03/9] ib/iser: remove atomic counter for posted recv buffers
[PATCH 04/9] ib/iser: use different CQ for send completions
[PATCH 05/9] ib/iser: simplify send flow/descriptors
[PATCH 06/9] ib/iser: use atomic allocations
[PATCH 07/9] ib/iser: remove unnecessary connection checks
[PATCH 08/9] ib/iser: move to use libiscsi passthrough mode
[PATCH 09/9] ib/iser: remove redundant locking from iser scsi command response flow
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 01/9] ib/iser: revert commit bba7ebb "avoid recv buffer exhaustion"
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
@ 2010-02-03 15:31 ` Or Gerlitz
2010-02-03 15:33 ` [PATCH 02/9] ib/iser: new recv buffer posting logic Or Gerlitz
` (10 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:31 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie, David Disseldorp, Ken Sandars
towards a major change in the recv buffer posting logic, with which
the problem commit bba7ebb "avoid recv buffer exhaustion caused by
unexpected PDUs" comes to solve doesn't exist any more, revert it.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
CC: David Disseldorp <ddiss-sJ/iWh9BUns@public.gmane.org>
CC: Ken Sandars <ksandars-sJ/iWh9BUns@public.gmane.org>
---
drivers/infiniband/ulp/iser/iscsi_iser.h | 3
drivers/infiniband/ulp/iser/iser_initiator.c | 144 ++++++++-------------------
drivers/infiniband/ulp/iser/iser_verbs.c | 1
3 files changed, 47 insertions(+), 101 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -252,9 +252,6 @@ struct iser_conn {
wait_queue_head_t wait; /* waitq for conn/disconn */
atomic_t post_recv_buf_count; /* posted rx 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];
struct iser_page_vec *page_vec; /* represents SG to fmr maps*
* maps serialized as tx is*/
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -183,8 +183,14 @@ static int iser_post_receive_control(str
struct iser_regd_buf *regd_data;
struct iser_dto *recv_dto = NULL;
struct iser_device *device = iser_conn->ib_conn->device;
- int rx_data_size, err;
- int posts, outstanding_unexp_pdus;
+ int rx_data_size, err = 0;
+
+ rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
+ if (rx_desc == NULL) {
+ iser_err("Failed to alloc desc for post recv\n");
+ return -ENOMEM;
+ }
+ rx_desc->type = ISCSI_RX;
/* for the login sequence we must support rx of upto 8K; login is done
* after conn create/bind (connect) and conn stop/bind (reconnect),
@@ -195,80 +201,46 @@ static int iser_post_receive_control(str
else /* FIXME till user space sets conn->max_recv_dlength correctly */
rx_data_size = 128;
- outstanding_unexp_pdus =
- atomic_xchg(&iser_conn->ib_conn->unexpected_pdu_count, 0);
+ rx_desc->data = kmalloc(rx_data_size, GFP_NOIO);
+ if (rx_desc->data == NULL) {
+ iser_err("Failed to alloc data buf for post recv\n");
+ err = -ENOMEM;
+ goto post_rx_kmalloc_failure;
+ }
- /*
- * in addition to the response buffer, replace those consumed by
- * unexpected pdus.
- */
- for (posts = 0; posts < 1 + outstanding_unexp_pdus; posts++) {
- rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
- if (rx_desc == NULL) {
- iser_err("Failed to alloc desc for post recv %d\n",
- posts);
- err = -ENOMEM;
- goto post_rx_cache_alloc_failure;
- }
- rx_desc->type = ISCSI_RX;
- rx_desc->data = kmalloc(rx_data_size, GFP_NOIO);
- if (rx_desc->data == NULL) {
- iser_err("Failed to alloc data buf for post recv %d\n",
- posts);
- err = -ENOMEM;
- goto post_rx_kmalloc_failure;
- }
+ recv_dto = &rx_desc->dto;
+ recv_dto->ib_conn = iser_conn->ib_conn;
+ recv_dto->regd_vector_len = 0;
- recv_dto = &rx_desc->dto;
- recv_dto->ib_conn = iser_conn->ib_conn;
- recv_dto->regd_vector_len = 0;
-
- regd_hdr = &rx_desc->hdr_regd_buf;
- memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
- regd_hdr->device = device;
- regd_hdr->virt_addr = rx_desc; /* == &rx_desc->iser_header */
- regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN;
-
- iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE);
-
- iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0);
-
- regd_data = &rx_desc->data_regd_buf;
- memset(regd_data, 0, sizeof(struct iser_regd_buf));
- regd_data->device = device;
- regd_data->virt_addr = rx_desc->data;
- regd_data->data_size = rx_data_size;
-
- iser_reg_single(device, regd_data, DMA_FROM_DEVICE);
-
- iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0);
-
- err = iser_post_recv(rx_desc);
- if (err) {
- iser_err("Failed iser_post_recv for post %d\n", posts);
- goto post_rx_post_recv_failure;
- }
- }
- /* all posts successful */
- return 0;
+ regd_hdr = &rx_desc->hdr_regd_buf;
+ memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
+ regd_hdr->device = device;
+ regd_hdr->virt_addr = rx_desc; /* == &rx_desc->iser_header */
+ regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN;
+
+ iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE);
+
+ iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0);
+
+ regd_data = &rx_desc->data_regd_buf;
+ memset(regd_data, 0, sizeof(struct iser_regd_buf));
+ regd_data->device = device;
+ regd_data->virt_addr = rx_desc->data;
+ regd_data->data_size = rx_data_size;
+
+ iser_reg_single(device, regd_data, DMA_FROM_DEVICE);
-post_rx_post_recv_failure:
+ iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0);
+
+ err = iser_post_recv(rx_desc);
+ if (!err)
+ return 0;
+
+ /* iser_post_recv failed */
iser_dto_buffs_release(recv_dto);
kfree(rx_desc->data);
post_rx_kmalloc_failure:
kmem_cache_free(ig.desc_cache, rx_desc);
-post_rx_cache_alloc_failure:
- if (posts > 0) {
- /*
- * response buffer posted, but did not replace all unexpected
- * pdu recv bufs. Ignore error, retry occurs next send
- */
- outstanding_unexp_pdus -= (posts - 1);
- err = 0;
- }
- atomic_add(outstanding_unexp_pdus,
- &iser_conn->ib_conn->unexpected_pdu_count);
-
return err;
}
@@ -302,10 +274,8 @@ int iser_conn_set_full_featured_mode(str
struct iscsi_iser_conn *iser_conn = conn->dd_data;
int i;
- /*
- * FIXME this value should be declared to the target during login with
- * the MaxOutstandingUnexpectedPDUs key when supported
- */
+ /* no need to keep it in a var, we are after login so if this should
+ * be negotiated, by now the result should be available here */
int initial_post_recv_bufs_num = ISER_MAX_RX_MISC_PDUS;
iser_dbg("Initially post: %d\n", initial_post_recv_bufs_num);
@@ -507,7 +477,6 @@ int iser_send_control(struct iscsi_conn
int err = 0;
struct iser_regd_buf *regd_buf;
struct iser_device *device;
- unsigned char opcode;
if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
@@ -542,15 +511,10 @@ int iser_send_control(struct iscsi_conn
data_seg_len);
}
- opcode = task->hdr->opcode & ISCSI_OPCODE_MASK;
-
- /* post recv buffer for response if one is expected */
- if (!(opcode == ISCSI_OP_NOOP_OUT && task->hdr->itt == RESERVED_ITT)) {
- if (iser_post_receive_control(conn) != 0) {
- iser_err("post_rcv_buff failed!\n");
- err = -ENOMEM;
- goto send_control_error;
- }
+ if (iser_post_receive_control(conn) != 0) {
+ iser_err("post_rcv_buff failed!\n");
+ err = -ENOMEM;
+ goto send_control_error;
}
err = iser_post_send(mdesc);
@@ -621,20 +585,6 @@ void iser_rcv_completion(struct iser_des
* parallel to the execution of iser_conn_term. So the code that waits *
* for the posted rx bufs refcount to become zero handles everything */
atomic_dec(&conn->ib_conn->post_recv_buf_count);
-
- /*
- * if an unexpected PDU was received then the recv wr consumed must
- * be replaced, this is done in the next send of a control-type PDU
- */
- if (opcode == ISCSI_OP_NOOP_IN && hdr->itt == RESERVED_ITT) {
- /* nop-in with itt = 0xffffffff */
- atomic_inc(&conn->ib_conn->unexpected_pdu_count);
- }
- else if (opcode == ISCSI_OP_ASYNC_EVENT) {
- /* asyncronous message */
- atomic_inc(&conn->ib_conn->unexpected_pdu_count);
- }
- /* a reject PDU consumes the recv buf posted for the response */
}
void iser_snd_completion(struct iser_desc *tx_desc)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_verbs.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -491,7 +491,6 @@ void iser_conn_init(struct iser_conn *ib
init_waitqueue_head(&ib_conn->wait);
atomic_set(&ib_conn->post_recv_buf_count, 0);
atomic_set(&ib_conn->post_send_buf_count, 0);
- atomic_set(&ib_conn->unexpected_pdu_count, 0);
atomic_set(&ib_conn->refcount, 1);
INIT_LIST_HEAD(&ib_conn->conn_list);
spin_lock_init(&ib_conn->lock);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 02/9] ib/iser: new recv buffer posting logic
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
2010-02-03 15:31 ` [PATCH 01/9] ib/iser: revert commit bba7ebb "avoid recv buffer exhaustion" Or Gerlitz
@ 2010-02-03 15:33 ` Or Gerlitz
2010-02-03 15:35 ` [PATCH 03/9] ib/iser: remove atomic counter for posted recv buffers Or Gerlitz
` (9 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:33 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie
Currently, the recv buffer posting logic is based on the transactional
nature of iser which allows for posting a buffer before sending a PDU.
Change this to post only when the number of outstanding recv buffers is
below a water mark and in a batched manner, thus simplifying and
optimizing the data path. Use a pre-allocated ring of recv buffers
instead of allocating from kmem cache. A special treatment is given
to the login response buffer whose size must be 8K unlike the size
of buffers used for any other purpose which is 128 bytes.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 2
drivers/infiniband/ulp/iser/iscsi_iser.h | 40 +++-
drivers/infiniband/ulp/iser/iser_initiator.c | 235 +++++++++++++--------------
drivers/infiniband/ulp/iser/iser_verbs.c | 134 +++++++++------
4 files changed, 235 insertions(+), 176 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -102,9 +102,9 @@
#define ISER_MAX_TX_MISC_PDUS 6 /* NOOP_OUT(2), TEXT(1), *
* SCSI_TMFUNC(2), LOGOUT(1) */
-#define ISER_QP_MAX_RECV_DTOS (ISCSI_DEF_XMIT_CMDS_MAX + \
- ISER_MAX_RX_MISC_PDUS + \
- ISER_MAX_TX_MISC_PDUS)
+#define ISER_QP_MAX_RECV_DTOS (ISCSI_DEF_XMIT_CMDS_MAX)
+
+#define ISER_MIN_POSTED_RX (ISCSI_DEF_XMIT_CMDS_MAX >> 2)
/* 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 *
@@ -132,6 +132,12 @@ struct iser_hdr {
__be64 read_va;
} __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 */
#define ISER_OBJECT_NAME_SIZE 64
@@ -212,7 +218,6 @@ struct iser_dto {
};
enum iser_desc_type {
- ISCSI_RX,
ISCSI_TX_CONTROL ,
ISCSI_TX_SCSI_COMMAND,
ISCSI_TX_DATAOUT
@@ -228,6 +233,17 @@ struct iser_desc {
struct iser_dto dto;
};
+#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 ib_device *ib_device;
struct ib_pd *pd;
@@ -256,6 +272,12 @@ struct iser_conn {
struct iser_page_vec *page_vec; /* represents SG to fmr maps*
* maps serialized as tx is*/
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 {
@@ -319,8 +341,9 @@ void iser_conn_put(struct iser_conn *ib_
void iser_conn_terminate(struct iser_conn *ib_conn);
-void iser_rcv_completion(struct iser_desc *desc,
- unsigned long dto_xfer_len);
+void iser_rcv_completion(struct iser_rx_desc *desc,
+ unsigned long dto_xfer_len,
+ struct iser_conn *ib_conn);
void iser_snd_completion(struct iser_desc *desc);
@@ -332,6 +355,8 @@ void iser_dto_buffs_release(struct iser_
int iser_regd_buff_release(struct iser_regd_buf *regd_buf);
+void iser_free_rx_descriptors(struct iser_conn *ib_conn);
+
void iser_reg_single(struct iser_device *device,
struct iser_regd_buf *regd_buf,
enum dma_data_direction direction);
@@ -353,7 +378,8 @@ int iser_reg_page_vec(struct iser_conn
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_recvm(struct iser_conn *ib_conn, int count);
int iser_post_send(struct iser_desc *tx_desc);
int iser_conn_state_comp(struct iser_conn *ib_conn,
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -39,9 +39,6 @@
#include "iscsi_iser.h"
-/* Constant PDU lengths calculations */
-#define ISER_TOTAL_HEADERS_LEN (sizeof (struct iser_hdr) + \
- sizeof (struct iscsi_hdr))
/* iser_dto_add_regd_buff - increments the reference count for *
* the registered buffer & adds it to the DTO object */
@@ -172,78 +169,6 @@ iser_prepare_write_cmd(struct iscsi_task
return 0;
}
-/**
- * iser_post_receive_control - allocates, initializes and posts receive DTO.
- */
-static int iser_post_receive_control(struct iscsi_conn *conn)
-{
- struct iscsi_iser_conn *iser_conn = conn->dd_data;
- struct iser_desc *rx_desc;
- struct iser_regd_buf *regd_hdr;
- struct iser_regd_buf *regd_data;
- struct iser_dto *recv_dto = NULL;
- struct iser_device *device = iser_conn->ib_conn->device;
- int rx_data_size, err = 0;
-
- rx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
- if (rx_desc == NULL) {
- iser_err("Failed to alloc desc for post recv\n");
- return -ENOMEM;
- }
- rx_desc->type = ISCSI_RX;
-
- /* for the login sequence we must support rx of upto 8K; login is done
- * after conn create/bind (connect) and conn stop/bind (reconnect),
- * what's common for both schemes is that the connection is not started
- */
- if (conn->c_stage != ISCSI_CONN_STARTED)
- rx_data_size = ISCSI_DEF_MAX_RECV_SEG_LEN;
- else /* FIXME till user space sets conn->max_recv_dlength correctly */
- rx_data_size = 128;
-
- rx_desc->data = kmalloc(rx_data_size, GFP_NOIO);
- if (rx_desc->data == NULL) {
- iser_err("Failed to alloc data buf for post recv\n");
- err = -ENOMEM;
- goto post_rx_kmalloc_failure;
- }
-
- recv_dto = &rx_desc->dto;
- recv_dto->ib_conn = iser_conn->ib_conn;
- recv_dto->regd_vector_len = 0;
-
- regd_hdr = &rx_desc->hdr_regd_buf;
- memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
- regd_hdr->device = device;
- regd_hdr->virt_addr = rx_desc; /* == &rx_desc->iser_header */
- regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN;
-
- iser_reg_single(device, regd_hdr, DMA_FROM_DEVICE);
-
- iser_dto_add_regd_buff(recv_dto, regd_hdr, 0, 0);
-
- regd_data = &rx_desc->data_regd_buf;
- memset(regd_data, 0, sizeof(struct iser_regd_buf));
- regd_data->device = device;
- regd_data->virt_addr = rx_desc->data;
- regd_data->data_size = rx_data_size;
-
- iser_reg_single(device, regd_data, DMA_FROM_DEVICE);
-
- iser_dto_add_regd_buff(recv_dto, regd_data, 0, 0);
-
- err = iser_post_recv(rx_desc);
- if (!err)
- return 0;
-
- /* iser_post_recv failed */
- iser_dto_buffs_release(recv_dto);
- kfree(rx_desc->data);
-post_rx_kmalloc_failure:
- kmem_cache_free(ig.desc_cache, rx_desc);
- return err;
-}
-
/* creates a new tx descriptor and adds header regd buffer */
static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn,
struct iser_desc *tx_desc)
@@ -254,7 +179,7 @@ static void iser_create_send_desc(struct
memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
regd_hdr->device = iser_conn->ib_conn->device;
regd_hdr->virt_addr = tx_desc; /* == &tx_desc->iser_header */
- regd_hdr->data_size = ISER_TOTAL_HEADERS_LEN;
+ regd_hdr->data_size = ISER_HEADERS_LEN;
send_dto->ib_conn = iser_conn->ib_conn;
send_dto->notify_enable = 1;
@@ -266,6 +191,72 @@ static void iser_create_send_desc(struct
iser_dto_add_regd_buff(send_dto, regd_hdr, 0, 0);
}
+int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
+{
+ int i, j;
+ u64 dma_addr;
+ struct iser_rx_desc *rx_desc;
+ struct ib_sge *rx_sg;
+ struct iser_device *device = ib_conn->device;
+
+ ib_conn->rx_descs = kmalloc(ISER_QP_MAX_RECV_DTOS *
+ sizeof(struct iser_rx_desc), GFP_KERNEL);
+ if (!ib_conn->rx_descs)
+ goto rx_desc_alloc_fail;
+
+ rx_desc = ib_conn->rx_descs;
+
+ for (i = 0; i < ISER_QP_MAX_RECV_DTOS; i++, rx_desc++) {
+ dma_addr = ib_dma_map_single(device->ib_device, (void *)rx_desc,
+ ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
+ if (ib_dma_mapping_error(device->ib_device, dma_addr))
+ goto rx_desc_dma_map_failed;
+
+ rx_desc->dma_addr = dma_addr;
+
+ rx_sg = &rx_desc->rx_sg;
+ rx_sg->addr = rx_desc->dma_addr;
+ rx_sg->length = ISER_RX_PAYLOAD_SIZE;
+ rx_sg->lkey = device->mr->lkey;
+ }
+
+ ib_conn->rx_desc_head = 0;
+ return 0;
+
+rx_desc_dma_map_failed:
+ rx_desc = ib_conn->rx_descs;
+ for (j = 0; j < i; j++, rx_desc++)
+ ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr,
+ ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
+ kfree(ib_conn->rx_descs);
+ ib_conn->rx_descs = NULL;
+rx_desc_alloc_fail:
+ iser_err("failed allocating rx descriptors / data buffers\n");
+ return -ENOMEM;
+}
+
+void iser_free_rx_descriptors(struct iser_conn *ib_conn)
+{
+ int i;
+ struct iser_rx_desc *rx_desc;
+ struct iser_device *device = ib_conn->device;
+
+ if (ib_conn->login_buf) {
+ ib_dma_unmap_single(device->ib_device, ib_conn->login_dma,
+ ISER_RX_LOGIN_SIZE, DMA_FROM_DEVICE);
+ kfree(ib_conn->login_buf);
+ }
+
+ if (!ib_conn->rx_descs)
+ return;
+
+ rx_desc = ib_conn->rx_descs;
+ for (i = 0; i < ISER_QP_MAX_RECV_DTOS; i++, rx_desc++)
+ ib_dma_unmap_single(device->ib_device, rx_desc->dma_addr,
+ ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
+ kfree(ib_conn->rx_descs);
+}
+
/**
* iser_conn_set_full_featured_mode - (iSER API)
*/
@@ -273,27 +264,20 @@ int iser_conn_set_full_featured_mode(str
{
struct iscsi_iser_conn *iser_conn = conn->dd_data;
- int i;
- /* no need to keep it in a var, we are after login so if this should
- * be negotiated, by now the result should be available here */
- int initial_post_recv_bufs_num = ISER_MAX_RX_MISC_PDUS;
-
- iser_dbg("Initially post: %d\n", initial_post_recv_bufs_num);
+ iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX);
/* Check that there is no posted recv or send buffers left - */
/* they must be consumed during the login phase */
BUG_ON(atomic_read(&iser_conn->ib_conn->post_recv_buf_count) != 0);
BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);
+ if (iser_alloc_rx_descriptors(iser_conn->ib_conn))
+ return -ENOMEM;
+
/* Initial post receive buffers */
- for (i = 0; i < initial_post_recv_bufs_num; i++) {
- if (iser_post_receive_control(conn) != 0) {
- iser_err("Failed to post recv bufs at:%d conn:0x%p\n",
- i, conn);
- return -ENOMEM;
- }
- }
- iser_dbg("Posted %d post recv bufs, conn:0x%p\n", i, conn);
+ if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX))
+ return -ENOMEM;
+
return 0;
}
@@ -321,7 +305,7 @@ int iser_send_command(struct iscsi_conn
struct iscsi_iser_task *iser_task = task->dd_data;
struct iser_dto *send_dto = NULL;
unsigned long edtl;
- int err = 0;
+ int err;
struct iser_data_buf *data_buf;
struct iscsi_cmd *hdr = (struct iscsi_cmd *)task->hdr;
struct scsi_cmnd *sc = task->sc;
@@ -371,12 +355,6 @@ int iser_send_command(struct iscsi_conn
iser_reg_single(iser_conn->ib_conn->device,
send_dto->regd[0], DMA_TO_DEVICE);
- if (iser_post_receive_control(conn) != 0) {
- iser_err("post_recv failed!\n");
- err = -ENOMEM;
- goto send_command_error;
- }
-
iser_task->status = ISER_TASK_STATUS_STARTED;
err = iser_post_send(&iser_task->desc);
@@ -474,7 +452,7 @@ int iser_send_control(struct iscsi_conn
struct iser_desc *mdesc = &iser_task->desc;
struct iser_dto *send_dto = NULL;
unsigned long data_seg_len;
- int err = 0;
+ int err;
struct iser_regd_buf *regd_buf;
struct iser_device *device;
@@ -511,10 +489,10 @@ int iser_send_control(struct iscsi_conn
data_seg_len);
}
- if (iser_post_receive_control(conn) != 0) {
- iser_err("post_rcv_buff failed!\n");
- err = -ENOMEM;
- goto send_control_error;
+ if (task == conn->login_task) {
+ err = iser_post_recvl(iser_conn->ib_conn);
+ if (err)
+ goto send_control_error;
}
err = iser_post_send(mdesc);
@@ -530,27 +508,34 @@ send_control_error:
/**
* iser_rcv_dto_completion - recv DTO completion
*/
-void iser_rcv_completion(struct iser_desc *rx_desc,
- unsigned long dto_xfer_len)
+void iser_rcv_completion(struct iser_rx_desc *rx_desc,
+ unsigned long rx_xfer_len,
+ struct iser_conn *ib_conn)
{
- struct iser_dto *dto = &rx_desc->dto;
- struct iscsi_iser_conn *conn = dto->ib_conn->iser_conn;
+ struct iscsi_iser_conn *conn = ib_conn->iser_conn;
struct iscsi_task *task;
struct iscsi_iser_task *iser_task;
struct iscsi_hdr *hdr;
- char *rx_data = NULL;
- int rx_data_len = 0;
unsigned char opcode;
+ u64 rx_dma;
+ int rx_buflen, outstanding, count, err;
- hdr = &rx_desc->iscsi_header;
+ /* differentiate between login to all other PDUs */
+ if ((char *)rx_desc == ib_conn->login_buf) {
+ rx_dma = ib_conn->login_dma;
+ rx_buflen = ISER_RX_LOGIN_SIZE;
+ } else {
+ rx_dma = rx_desc->dma_addr;
+ rx_buflen = ISER_RX_PAYLOAD_SIZE;
+ }
- iser_dbg("op 0x%x itt 0x%x\n", hdr->opcode,hdr->itt);
+ ib_dma_sync_single_for_cpu(ib_conn->device->ib_device, rx_dma,
+ rx_buflen, DMA_FROM_DEVICE);
- if (dto_xfer_len > ISER_TOTAL_HEADERS_LEN) { /* we have data */
- rx_data_len = dto_xfer_len - ISER_TOTAL_HEADERS_LEN;
- rx_data = dto->regd[1]->virt_addr;
- rx_data += dto->offset[1];
- }
+ hdr = &rx_desc->iscsi_header;
+
+ iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
+ hdr->itt, (int)(rx_xfer_len - ISER_HEADERS_LEN));
opcode = hdr->opcode & ISCSI_OPCODE_MASK;
@@ -573,18 +558,30 @@ void iser_rcv_completion(struct iser_des
iscsi_put_task(task);
}
}
- iser_dto_buffs_release(dto);
- iscsi_iser_recv(conn->iscsi_conn, hdr, rx_data, rx_data_len);
+ iscsi_iser_recv(conn->iscsi_conn, hdr,
+ rx_desc->data, rx_xfer_len - ISER_HEADERS_LEN);
- kfree(rx_desc->data);
- kmem_cache_free(ig.desc_cache, rx_desc);
+ ib_dma_sync_single_for_device(ib_conn->device->ib_device, rx_dma,
+ rx_buflen, DMA_FROM_DEVICE);
/* decrementing conn->post_recv_buf_count only --after-- freeing the *
* task eliminates the need to worry on tasks which are completed in *
* parallel to the execution of iser_conn_term. So the code that waits *
* for the posted rx bufs refcount to become zero handles everything */
atomic_dec(&conn->ib_conn->post_recv_buf_count);
+
+ if (rx_dma == ib_conn->login_dma)
+ return;
+
+ outstanding = atomic_read(&ib_conn->post_recv_buf_count);
+ if (outstanding + ISER_MIN_POSTED_RX <= ISER_QP_MAX_RECV_DTOS) {
+ count = min(ISER_QP_MAX_RECV_DTOS - outstanding,
+ ISER_MIN_POSTED_RX);
+ err = iser_post_recvm(ib_conn, count);
+ if (err)
+ iser_err("posting %d rx bufs err %d\n", count, err);
+ }
}
void iser_snd_completion(struct iser_desc *tx_desc)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_verbs.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -129,13 +129,23 @@ static int iser_create_ib_conn_res(struc
{
struct iser_device *device;
struct ib_qp_init_attr init_attr;
- int ret;
+ int ret = -ENOMEM;
struct ib_fmr_pool_param params;
BUG_ON(ib_conn->device == NULL);
device = ib_conn->device;
+ ib_conn->login_buf = kmalloc(ISER_RX_LOGIN_SIZE, GFP_KERNEL);
+ if (!ib_conn->login_buf) {
+ goto alloc_err;
+ ret = -ENOMEM;
+ }
+
+ ib_conn->login_dma = ib_dma_map_single(ib_conn->device->ib_device,
+ (void *)ib_conn->login_buf, ISER_RX_LOGIN_SIZE,
+ DMA_FROM_DEVICE);
+
ib_conn->page_vec = kmalloc(sizeof(struct iser_page_vec) +
(sizeof(u64) * (ISCSI_ISER_SG_TABLESIZE +1)),
GFP_KERNEL);
@@ -174,7 +184,7 @@ static int iser_create_ib_conn_res(struc
init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN;
- init_attr.cap.max_recv_sge = 2;
+ init_attr.cap.max_recv_sge = 1;
init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
init_attr.qp_type = IB_QPT_RC;
@@ -192,6 +202,7 @@ qp_err:
(void)ib_destroy_fmr_pool(ib_conn->fmr_pool);
fmr_pool_err:
kfree(ib_conn->page_vec);
+ kfree(ib_conn->login_buf);
alloc_err:
iser_err("unable to alloc mem or create resource, err %d\n", ret);
return ret;
@@ -314,7 +325,7 @@ static void iser_conn_release(struct ise
mutex_lock(&ig.connlist_mutex);
list_del(&ib_conn->conn_list);
mutex_unlock(&ig.connlist_mutex);
-
+ iser_free_rx_descriptors(ib_conn);
iser_free_ib_conn_res(ib_conn);
ib_conn->device = NULL;
/* on EVENT_ADDR_ERROR there's no device yet for this conn */
@@ -625,6 +636,60 @@ void iser_unreg_mem(struct iser_mem_reg
reg->mem_h = NULL;
}
+int iser_post_recvl(struct iser_conn *ib_conn)
+{
+ struct ib_recv_wr rx_wr, *rx_wr_failed;
+ struct ib_sge sge;
+ int ib_ret;
+
+ sge.addr = ib_conn->login_dma;
+ sge.length = ISER_RX_LOGIN_SIZE;
+ sge.lkey = ib_conn->device->mr->lkey;
+
+ rx_wr.wr_id = (unsigned long)ib_conn->login_buf;
+ rx_wr.sg_list = &sge;
+ rx_wr.num_sge = 1;
+ rx_wr.next = NULL;
+
+ atomic_inc(&ib_conn->post_recv_buf_count);
+ ib_ret = ib_post_recv(ib_conn->qp, &rx_wr, &rx_wr_failed);
+ if (ib_ret) {
+ iser_err("ib_post_recv failed ret=%d\n", ib_ret);
+ atomic_dec(&ib_conn->post_recv_buf_count);
+ }
+ return ib_ret;
+}
+
+int iser_post_recvm(struct iser_conn *ib_conn, int count)
+{
+ struct ib_recv_wr *rx_wr, *rx_wr_failed;
+ int i, ib_ret;
+ unsigned int my_rx_head = ib_conn->rx_desc_head;
+ struct iser_rx_desc *rx_desc;
+
+ for (rx_wr = ib_conn->rx_wr, i = 0; i < count; i++, rx_wr++) {
+ rx_desc = &ib_conn->rx_descs[my_rx_head];
+ rx_wr->wr_id = (unsigned long)rx_desc;
+ rx_wr->sg_list = &rx_desc->rx_sg;
+ rx_wr->num_sge = 1;
+ rx_wr->next = rx_wr + 1;
+ my_rx_head = (my_rx_head + 1) & (ISER_QP_MAX_RECV_DTOS - 1);
+ }
+
+ rx_wr--;
+ rx_wr->next = NULL; /* mark end of work requests list */
+
+ atomic_add(count, &ib_conn->post_recv_buf_count);
+ ib_ret = ib_post_recv(ib_conn->qp, ib_conn->rx_wr, &rx_wr_failed);
+ if (ib_ret) {
+ iser_err("ib_post_recv failed ret=%d\n", ib_ret);
+ atomic_sub(count, &ib_conn->post_recv_buf_count);
+ } else
+ ib_conn->rx_desc_head = my_rx_head;
+ return ib_ret;
+}
+
+
/**
* iser_dto_to_iov - builds IOV from a dto descriptor
*/
@@ -665,39 +730,6 @@ static void iser_dto_to_iov(struct iser_
}
}
-/**
- * iser_post_recv - Posts a receive buffer.
- *
- * returns 0 on success, -1 on failure
- */
-int iser_post_recv(struct iser_desc *rx_desc)
-{
- int ib_ret, ret_val = 0;
- struct ib_recv_wr recv_wr, *recv_wr_failed;
- struct ib_sge iov[2];
- struct iser_conn *ib_conn;
- struct iser_dto *recv_dto = &rx_desc->dto;
-
- /* Retrieve conn */
- ib_conn = recv_dto->ib_conn;
-
- iser_dto_to_iov(recv_dto, iov, 2);
-
- recv_wr.next = NULL;
- recv_wr.sg_list = iov;
- recv_wr.num_sge = recv_dto->regd_vector_len;
- recv_wr.wr_id = (unsigned long)rx_desc;
-
- atomic_inc(&ib_conn->post_recv_buf_count);
- ib_ret = ib_post_recv(ib_conn->qp, &recv_wr, &recv_wr_failed);
- if (ib_ret) {
- iser_err("ib_post_recv failed ret=%d\n", ib_ret);
- atomic_dec(&ib_conn->post_recv_buf_count);
- ret_val = -1;
- }
-
- return ret_val;
-}
/**
* iser_start_send - Initiate a Send DTO operation
@@ -737,18 +769,17 @@ int iser_post_send(struct iser_desc *tx_
return ret_val;
}
-static void iser_handle_comp_error(struct iser_desc *desc)
+static void iser_handle_comp_error(struct iser_desc *desc,
+ struct iser_conn *ib_conn)
{
- struct iser_dto *dto = &desc->dto;
- struct iser_conn *ib_conn = dto->ib_conn;
+ struct iser_rx_desc *rx = (struct iser_rx_desc *)desc;
+ struct iser_rx_desc *rx_first = ib_conn->rx_descs;
+ struct iser_rx_desc *rx_last = rx_first + (ISER_QP_MAX_RECV_DTOS - 1);
- iser_dto_buffs_release(dto);
-
- if (desc->type == ISCSI_RX) {
- kfree(desc->data);
- kmem_cache_free(ig.desc_cache, desc);
+ if ((char *)desc == ib_conn->login_buf ||
+ (rx_first <= rx && rx <= rx_last))
atomic_dec(&ib_conn->post_recv_buf_count);
- } else { /* type is TX control/command/dataout */
+ else { /* type is TX control/command/dataout */
if (desc->type == ISCSI_TX_DATAOUT)
kmem_cache_free(ig.desc_cache, desc);
atomic_dec(&ib_conn->post_send_buf_count);
@@ -780,20 +811,25 @@ static void iser_cq_tasklet_fn(unsigned
struct ib_wc wc;
struct iser_desc *desc;
unsigned long xfer_len;
+ struct iser_conn *ib_conn;
while (ib_poll_cq(cq, 1, &wc) == 1) {
desc = (struct iser_desc *) (unsigned long) wc.wr_id;
BUG_ON(desc == NULL);
+ ib_conn = wc.qp->qp_context;
if (wc.status == IB_WC_SUCCESS) {
- if (desc->type == ISCSI_RX) {
+ if (wc.opcode == IB_WC_RECV) {
xfer_len = (unsigned long)wc.byte_len;
- iser_rcv_completion(desc, xfer_len);
+ iser_rcv_completion((struct iser_rx_desc *)desc,
+ xfer_len, ib_conn);
} else /* type == ISCSI_TX_CONTROL/SCSI_CMD/DOUT */
iser_snd_completion(desc);
} else {
- iser_err("comp w. error op %d status %d\n",desc->type,wc.status);
- iser_handle_comp_error(desc);
+ if (wc.status != IB_WC_WR_FLUSH_ERR)
+ iser_err("id %llx status %d vend_err %x\n",
+ wc.wr_id, wc.status, wc.vendor_err);
+ iser_handle_comp_error(desc, ib_conn);
}
}
/* #warning "it is assumed here that arming CQ only once its empty" *
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -283,7 +283,7 @@ iscsi_iser_conn_create(struct iscsi_cls_
* due to issues with the login code re iser sematics
* 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;
conn->dd_data = iser_conn;
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 03/9] ib/iser: remove atomic counter for posted recv buffers
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
2010-02-03 15:31 ` [PATCH 01/9] ib/iser: revert commit bba7ebb "avoid recv buffer exhaustion" Or Gerlitz
2010-02-03 15:33 ` [PATCH 02/9] ib/iser: new recv buffer posting logic Or Gerlitz
@ 2010-02-03 15:35 ` Or Gerlitz
2010-02-03 15:36 ` [PATCH 04/9] ib/iser: use different CQ for send completions Or Gerlitz
` (8 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:35 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie
With both the posting and reaping of recv buffers being in the
completion path, their outstanding number counter need not be atomic.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
---
drivers/infiniband/ulp/iser/iscsi_iser.h | 2 +-
drivers/infiniband/ulp/iser/iser_initiator.c | 6 +++---
drivers/infiniband/ulp/iser/iser_verbs.c | 16 ++++++++--------
3 files changed, 12 insertions(+), 12 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -266,7 +266,7 @@ struct iser_conn {
struct ib_fmr_pool *fmr_pool; /* pool of IB FMRs */
int disc_evt_flag; /* disconn event delivered */
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 */
char name[ISER_OBJECT_NAME_SIZE];
struct iser_page_vec *page_vec; /* represents SG to fmr maps*
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -268,7 +268,7 @@ int iser_conn_set_full_featured_mode(str
/* Check that there is no posted recv or send buffers left - */
/* they must be consumed during the login phase */
- BUG_ON(atomic_read(&iser_conn->ib_conn->post_recv_buf_count) != 0);
+ BUG_ON(iser_conn->ib_conn->post_recv_buf_count != 0);
BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);
if (iser_alloc_rx_descriptors(iser_conn->ib_conn))
@@ -569,12 +569,12 @@ void iser_rcv_completion(struct iser_rx_
* task eliminates the need to worry on tasks which are completed in *
* parallel to the execution of iser_conn_term. So the code that waits *
* for the posted rx bufs refcount to become zero handles everything */
- atomic_dec(&conn->ib_conn->post_recv_buf_count);
+ conn->ib_conn->post_recv_buf_count--;
if (rx_dma == ib_conn->login_dma)
return;
- outstanding = atomic_read(&ib_conn->post_recv_buf_count);
+ outstanding = ib_conn->post_recv_buf_count;
if (outstanding + ISER_MIN_POSTED_RX <= ISER_QP_MAX_RECV_DTOS) {
count = min(ISER_QP_MAX_RECV_DTOS - outstanding,
ISER_MIN_POSTED_RX);
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_verbs.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -453,7 +453,7 @@ static void iser_disconnected_handler(st
ISCSI_ERR_CONN_FAILED);
/* Complete the termination process if no posts are pending */
- if ((atomic_read(&ib_conn->post_recv_buf_count) == 0) &&
+ if (ib_conn->post_recv_buf_count == 0 &&
(atomic_read(&ib_conn->post_send_buf_count) == 0)) {
ib_conn->state = ISER_CONN_DOWN;
wake_up_interruptible(&ib_conn->wait);
@@ -500,7 +500,7 @@ void iser_conn_init(struct iser_conn *ib
{
ib_conn->state = ISER_CONN_INIT;
init_waitqueue_head(&ib_conn->wait);
- atomic_set(&ib_conn->post_recv_buf_count, 0);
+ ib_conn->post_recv_buf_count = 0;
atomic_set(&ib_conn->post_send_buf_count, 0);
atomic_set(&ib_conn->refcount, 1);
INIT_LIST_HEAD(&ib_conn->conn_list);
@@ -651,11 +651,11 @@ int iser_post_recvl(struct iser_conn *ib
rx_wr.num_sge = 1;
rx_wr.next = NULL;
- atomic_inc(&ib_conn->post_recv_buf_count);
+ ib_conn->post_recv_buf_count++;
ib_ret = ib_post_recv(ib_conn->qp, &rx_wr, &rx_wr_failed);
if (ib_ret) {
iser_err("ib_post_recv failed ret=%d\n", ib_ret);
- atomic_dec(&ib_conn->post_recv_buf_count);
+ ib_conn->post_recv_buf_count--;
}
return ib_ret;
}
@@ -679,11 +679,11 @@ int iser_post_recvm(struct iser_conn *ib
rx_wr--;
rx_wr->next = NULL; /* mark end of work requests list */
- atomic_add(count, &ib_conn->post_recv_buf_count);
+ ib_conn->post_recv_buf_count += count;
ib_ret = ib_post_recv(ib_conn->qp, ib_conn->rx_wr, &rx_wr_failed);
if (ib_ret) {
iser_err("ib_post_recv failed ret=%d\n", ib_ret);
- atomic_sub(count, &ib_conn->post_recv_buf_count);
+ ib_conn->post_recv_buf_count -= count;
} else
ib_conn->rx_desc_head = my_rx_head;
return ib_ret;
@@ -778,14 +778,14 @@ static void iser_handle_comp_error(struc
if ((char *)desc == ib_conn->login_buf ||
(rx_first <= rx && rx <= rx_last))
- atomic_dec(&ib_conn->post_recv_buf_count);
+ ib_conn->post_recv_buf_count--;
else { /* type is TX control/command/dataout */
if (desc->type == ISCSI_TX_DATAOUT)
kmem_cache_free(ig.desc_cache, desc);
atomic_dec(&ib_conn->post_send_buf_count);
}
- if (atomic_read(&ib_conn->post_recv_buf_count) == 0 &&
+ if (ib_conn->post_recv_buf_count == 0 &&
atomic_read(&ib_conn->post_send_buf_count) == 0) {
/* getting here when the state is UP means that the conn is *
* being terminated asynchronously from the iSCSI layer's *
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 04/9] ib/iser: use different CQ for send completions
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
` (2 preceding siblings ...)
2010-02-03 15:35 ` [PATCH 03/9] ib/iser: remove atomic counter for posted recv buffers Or Gerlitz
@ 2010-02-03 15:36 ` Or Gerlitz
2010-02-03 15:37 ` [PATCH 05/9] ib/iser: simplify send flow/descriptors Or Gerlitz
` (7 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:36 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie
Use a different CQ for send completions, where send completions are
being polled by the interrupt driven recv completion handler.
As such, interrupts aren't used for the send CQ.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
---
drivers/infiniband/ulp/iser/iscsi_iser.h | 3
drivers/infiniband/ulp/iser/iser_verbs.c | 110 ++++++++++++++++++++-----------
2 files changed, 76 insertions(+), 37 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -247,7 +247,8 @@ struct iser_rx_desc {
struct iser_device {
struct ib_device *ib_device;
struct ib_pd *pd;
- struct ib_cq *cq;
+ struct ib_cq *rx_cq;
+ struct ib_cq *tx_cq;
struct ib_mr *mr;
struct tasklet_struct cq_tasklet;
struct list_head ig_list; /* entry in ig devices list */
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_verbs.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -37,9 +37,8 @@
#include "iscsi_iser.h"
#define ISCSI_ISER_MAX_CONN 8
-#define ISER_MAX_CQ_LEN ((ISER_QP_MAX_RECV_DTOS + \
- ISER_QP_MAX_REQ_DTOS) * \
- ISCSI_ISER_MAX_CONN)
+#define ISER_MAX_RX_CQ_LEN (ISER_QP_MAX_RECV_DTOS * ISCSI_ISER_MAX_CONN)
+#define ISER_MAX_TX_CQ_LEN (ISER_QP_MAX_REQ_DTOS * ISCSI_ISER_MAX_CONN)
static void iser_cq_tasklet_fn(unsigned long data);
static void iser_cq_callback(struct ib_cq *cq, void *cq_context);
@@ -67,15 +66,23 @@ static int iser_create_device_ib_res(str
if (IS_ERR(device->pd))
goto pd_err;
- device->cq = ib_create_cq(device->ib_device,
+ device->rx_cq = ib_create_cq(device->ib_device,
iser_cq_callback,
iser_cq_event_callback,
(void *)device,
- ISER_MAX_CQ_LEN, 0);
- if (IS_ERR(device->cq))
- goto cq_err;
+ ISER_MAX_RX_CQ_LEN, 0);
+ if (IS_ERR(device->rx_cq))
+ goto rx_cq_err;
- if (ib_req_notify_cq(device->cq, IB_CQ_NEXT_COMP))
+ device->tx_cq = ib_create_cq(device->ib_device,
+ NULL, iser_cq_event_callback,
+ (void *)device,
+ ISER_MAX_TX_CQ_LEN, 0);
+
+ if (IS_ERR(device->tx_cq))
+ goto tx_cq_err;
+
+ if (ib_req_notify_cq(device->rx_cq, IB_CQ_NEXT_COMP))
goto cq_arm_err;
tasklet_init(&device->cq_tasklet,
@@ -93,8 +100,10 @@ static int iser_create_device_ib_res(str
dma_mr_err:
tasklet_kill(&device->cq_tasklet);
cq_arm_err:
- ib_destroy_cq(device->cq);
-cq_err:
+ ib_destroy_cq(device->tx_cq);
+tx_cq_err:
+ ib_destroy_cq(device->rx_cq);
+rx_cq_err:
ib_dealloc_pd(device->pd);
pd_err:
iser_err("failed to allocate an IB resource\n");
@@ -112,11 +121,13 @@ static void iser_free_device_ib_res(stru
tasklet_kill(&device->cq_tasklet);
(void)ib_dereg_mr(device->mr);
- (void)ib_destroy_cq(device->cq);
+ (void)ib_destroy_cq(device->tx_cq);
+ (void)ib_destroy_cq(device->rx_cq);
(void)ib_dealloc_pd(device->pd);
device->mr = NULL;
- device->cq = NULL;
+ device->tx_cq = NULL;
+ device->rx_cq = NULL;
device->pd = NULL;
}
@@ -179,8 +190,8 @@ static int iser_create_ib_conn_res(struc
init_attr.event_handler = iser_qp_event_callback;
init_attr.qp_context = (void *)ib_conn;
- init_attr.send_cq = device->cq;
- init_attr.recv_cq = device->cq;
+ init_attr.send_cq = device->tx_cq;
+ init_attr.recv_cq = device->rx_cq;
init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN;
@@ -772,18 +783,8 @@ int iser_post_send(struct iser_desc *tx_
static void iser_handle_comp_error(struct iser_desc *desc,
struct iser_conn *ib_conn)
{
- struct iser_rx_desc *rx = (struct iser_rx_desc *)desc;
- struct iser_rx_desc *rx_first = ib_conn->rx_descs;
- struct iser_rx_desc *rx_last = rx_first + (ISER_QP_MAX_RECV_DTOS - 1);
-
- if ((char *)desc == ib_conn->login_buf ||
- (rx_first <= rx && rx <= rx_last))
- ib_conn->post_recv_buf_count--;
- else { /* type is TX control/command/dataout */
- if (desc->type == ISCSI_TX_DATAOUT)
- kmem_cache_free(ig.desc_cache, desc);
- atomic_dec(&ib_conn->post_send_buf_count);
- }
+ if (desc && desc->type == ISCSI_TX_DATAOUT)
+ kmem_cache_free(ig.desc_cache, desc);
if (ib_conn->post_recv_buf_count == 0 &&
atomic_read(&ib_conn->post_send_buf_count) == 0) {
@@ -804,37 +805,74 @@ static void iser_handle_comp_error(struc
}
}
+static int iser_drain_tx_cq(struct iser_device *device)
+{
+ struct ib_cq *cq = device->tx_cq;
+ struct ib_wc wc;
+ struct iser_desc *tx_desc;
+ struct iser_conn *ib_conn;
+ int completed_tx = 0;
+
+ while (ib_poll_cq(cq, 1, &wc) == 1) {
+ tx_desc = (struct iser_desc *) (unsigned long) wc.wr_id;
+ ib_conn = wc.qp->qp_context;
+ if (wc.status == IB_WC_SUCCESS) {
+ if (wc.opcode == IB_WC_SEND)
+ iser_snd_completion(tx_desc);
+ else
+ iser_err("expected opcode %d got %d\n",
+ IB_WC_SEND, wc.opcode);
+ } else {
+ iser_err("tx id %llx status %d vend_err %x\n",
+ wc.wr_id, wc.status, wc.vendor_err);
+ atomic_dec(&ib_conn->post_send_buf_count);
+ iser_handle_comp_error(tx_desc, ib_conn);
+ }
+ completed_tx++;
+ }
+ return completed_tx;
+}
+
+
static void iser_cq_tasklet_fn(unsigned long data)
{
struct iser_device *device = (struct iser_device *)data;
- struct ib_cq *cq = device->cq;
+ struct ib_cq *cq = device->rx_cq;
struct ib_wc wc;
- struct iser_desc *desc;
+ struct iser_rx_desc *desc;
unsigned long xfer_len;
struct iser_conn *ib_conn;
+ int completed_tx, completed_rx;
+ completed_tx = completed_rx = 0;
while (ib_poll_cq(cq, 1, &wc) == 1) {
- desc = (struct iser_desc *) (unsigned long) wc.wr_id;
+ desc = (struct iser_rx_desc *) (unsigned long) wc.wr_id;
BUG_ON(desc == NULL);
ib_conn = wc.qp->qp_context;
-
if (wc.status == IB_WC_SUCCESS) {
if (wc.opcode == IB_WC_RECV) {
xfer_len = (unsigned long)wc.byte_len;
- iser_rcv_completion((struct iser_rx_desc *)desc,
- xfer_len, ib_conn);
- } else /* type == ISCSI_TX_CONTROL/SCSI_CMD/DOUT */
- iser_snd_completion(desc);
+ iser_rcv_completion(desc, xfer_len, ib_conn);
+ } else
+ iser_err("expected opcode %d got %d\n",
+ IB_WC_RECV, wc.opcode);
} else {
if (wc.status != IB_WC_WR_FLUSH_ERR)
- iser_err("id %llx status %d vend_err %x\n",
+ iser_err("rx id %llx status %d vend_err %x\n",
wc.wr_id, wc.status, wc.vendor_err);
- iser_handle_comp_error(desc, ib_conn);
+ ib_conn->post_recv_buf_count--;
+ iser_handle_comp_error(NULL, ib_conn);
}
+ completed_rx++;
+ if (!(completed_rx & 63))
+ completed_tx += iser_drain_tx_cq(device);
}
/* #warning "it is assumed here that arming CQ only once its empty" *
* " would not cause interrupts to be missed" */
ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+
+ completed_tx += iser_drain_tx_cq(device);
+ iser_dbg("got %d rx %d tx completions\n", completed_rx, completed_tx);
}
static void iser_cq_callback(struct ib_cq *cq, void *cq_context)
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 05/9] ib/iser: simplify send flow/descriptors
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
` (3 preceding siblings ...)
2010-02-03 15:36 ` [PATCH 04/9] ib/iser: use different CQ for send completions Or Gerlitz
@ 2010-02-03 15:37 ` Or Gerlitz
[not found] ` <Pine.LNX.4.64.1002031737090.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
2010-02-03 15:39 ` [PATCH 06/9] ib/iser: use atomic allocations Or Gerlitz
` (6 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:37 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie
Simplify and shrink the logic/code used for the send descriptors.
Changes include removal of struct iser_dto which is unnecessary
abstraction, use struct iser_regd_buf only for handling SCSI commands,
use dma_sync instead of dma_map/unmap, etc.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 34 ++++-
drivers/infiniband/ulp/iser/iscsi_iser.h | 48 +------
drivers/infiniband/ulp/iser/iser_initiator.c | 182 +++++++++------------------
drivers/infiniband/ulp/iser/iser_memory.c | 60 --------
drivers/infiniband/ulp/iser/iser_verbs.c | 75 +----------
5 files changed, 118 insertions(+), 281 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -39,26 +39,6 @@
#include "iscsi_iser.h"
-
-/* iser_dto_add_regd_buff - increments the reference count for *
- * the registered buffer & adds it to the DTO object */
-static void iser_dto_add_regd_buff(struct iser_dto *dto,
- struct iser_regd_buf *regd_buf,
- unsigned long use_offset,
- unsigned long use_size)
-{
- int add_idx;
-
- atomic_inc(®d_buf->ref_count);
-
- add_idx = dto->regd_vector_len;
- dto->regd[add_idx] = regd_buf;
- dto->used_sz[add_idx] = use_size;
- dto->offset[add_idx] = use_offset;
-
- dto->regd_vector_len++;
-}
-
/* Register user buffer memory and initialize passive rdma
* dto descriptor. Total data size is stored in
* iser_task->data[ISER_DIR_IN].data_len
@@ -119,9 +99,9 @@ iser_prepare_write_cmd(struct iscsi_task
struct iscsi_iser_task *iser_task = task->dd_data;
struct iser_regd_buf *regd_buf;
int err;
- struct iser_dto *send_dto = &iser_task->desc.dto;
struct iser_hdr *hdr = &iser_task->desc.iser_header;
struct iser_data_buf *buf_out = &iser_task->data[ISER_DIR_OUT];
+ struct ib_sge *tx_dsg = &iser_task->desc.tx_sg[1];
err = iser_dma_map_task_data(iser_task,
buf_out,
@@ -160,37 +140,36 @@ iser_prepare_write_cmd(struct iscsi_task
if (imm_sz > 0) {
iser_dbg("Cmd itt:%d, WRITE, adding imm.data sz: %d\n",
task->itt, imm_sz);
- iser_dto_add_regd_buff(send_dto,
- regd_buf,
- 0,
- imm_sz);
+ tx_dsg->addr = regd_buf->reg.va;
+ tx_dsg->length = imm_sz;
+ tx_dsg->lkey = regd_buf->reg.lkey;
+ iser_task->desc.num_sge = 2;
}
return 0;
}
/* creates a new tx descriptor and adds header regd buffer */
-static void iser_create_send_desc(struct iscsi_iser_conn *iser_conn,
- struct iser_desc *tx_desc)
+static void iser_create_send_desc(struct iser_conn *ib_conn,
+ struct iser_tx_desc *tx_desc)
{
- struct iser_regd_buf *regd_hdr = &tx_desc->hdr_regd_buf;
- struct iser_dto *send_dto = &tx_desc->dto;
+ struct iser_device *device = ib_conn->device;
- memset(regd_hdr, 0, sizeof(struct iser_regd_buf));
- regd_hdr->device = iser_conn->ib_conn->device;
- regd_hdr->virt_addr = tx_desc; /* == &tx_desc->iser_header */
- regd_hdr->data_size = ISER_HEADERS_LEN;
-
- send_dto->ib_conn = iser_conn->ib_conn;
- send_dto->notify_enable = 1;
- send_dto->regd_vector_len = 0;
+ ib_dma_sync_single_for_cpu(device->ib_device,
+ tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
- memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr));
- tx_desc->iser_header.flags = ISER_VER;
+ memset(&tx_desc->iser_header, 0, sizeof(struct iser_hdr));
+ tx_desc->iser_header.flags = ISER_VER;
+
+ tx_desc->num_sge = 1;
- iser_dto_add_regd_buff(send_dto, regd_hdr, 0, 0);
+ if (tx_desc->tx_sg[0].lkey != device->mr->lkey) {
+ tx_desc->tx_sg[0].lkey = device->mr->lkey;
+ iser_dbg("sdesc %p lkey mismatch, fixing\n", tx_desc);
+ }
}
+
int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
{
int i, j;
@@ -303,12 +282,12 @@ int iser_send_command(struct iscsi_conn
{
struct iscsi_iser_conn *iser_conn = conn->dd_data;
struct iscsi_iser_task *iser_task = task->dd_data;
- struct iser_dto *send_dto = NULL;
unsigned long edtl;
int err;
struct iser_data_buf *data_buf;
struct iscsi_cmd *hdr = (struct iscsi_cmd *)task->hdr;
struct scsi_cmnd *sc = task->sc;
+ struct iser_tx_desc *tx_desc = &iser_task->desc;
if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
@@ -320,10 +299,8 @@ int iser_send_command(struct iscsi_conn
edtl = ntohl(hdr->data_length);
/* build the tx desc regd header and add it to the tx desc dto */
- iser_task->desc.type = ISCSI_TX_SCSI_COMMAND;
- send_dto = &iser_task->desc.dto;
- send_dto->task = iser_task;
- iser_create_send_desc(iser_conn, &iser_task->desc);
+ tx_desc->type = ISCSI_TX_SCSI_COMMAND;
+ iser_create_send_desc(iser_conn->ib_conn, tx_desc);
if (hdr->flags & ISCSI_FLAG_CMD_READ)
data_buf = &iser_task->data[ISER_DIR_IN];
@@ -352,17 +329,13 @@ int iser_send_command(struct iscsi_conn
goto send_command_error;
}
- iser_reg_single(iser_conn->ib_conn->device,
- send_dto->regd[0], DMA_TO_DEVICE);
-
iser_task->status = ISER_TASK_STATUS_STARTED;
- err = iser_post_send(&iser_task->desc);
+ err = iser_post_send(iser_conn->ib_conn, tx_desc);
if (!err)
return 0;
send_command_error:
- iser_dto_buffs_release(send_dto);
iser_err("conn %p failed task->itt %d err %d\n",conn, task->itt, err);
return err;
}
@@ -376,12 +349,14 @@ int iser_send_data_out(struct iscsi_conn
{
struct iscsi_iser_conn *iser_conn = conn->dd_data;
struct iscsi_iser_task *iser_task = task->dd_data;
- struct iser_desc *tx_desc = NULL;
- struct iser_dto *send_dto = NULL;
+ struct iser_tx_desc *tx_desc = NULL;
+ struct iser_regd_buf *regd_buf;
unsigned long buf_offset;
unsigned long data_seg_len;
uint32_t itt;
int err = 0;
+ struct ib_sge *tx_dsg;
+
if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
@@ -398,28 +373,25 @@ int iser_send_data_out(struct iscsi_conn
iser_dbg("%s itt %d dseg_len %d offset %d\n",
__func__,(int)itt,(int)data_seg_len,(int)buf_offset);
- tx_desc = kmem_cache_alloc(ig.desc_cache, GFP_NOIO);
+ tx_desc = kmem_cache_zalloc(ig.desc_cache, GFP_NOIO);
if (tx_desc == NULL) {
iser_err("Failed to alloc desc for post dataout\n");
return -ENOMEM;
}
tx_desc->type = ISCSI_TX_DATAOUT;
+ tx_desc->iser_header.flags = ISER_VER;
memcpy(&tx_desc->iscsi_header, hdr, sizeof(struct iscsi_hdr));
- /* build the tx desc regd header and add it to the tx desc dto */
- send_dto = &tx_desc->dto;
- send_dto->task = iser_task;
- iser_create_send_desc(iser_conn, tx_desc);
-
- iser_reg_single(iser_conn->ib_conn->device,
- send_dto->regd[0], DMA_TO_DEVICE);
-
- /* all data was registered for RDMA, we can use the lkey */
- iser_dto_add_regd_buff(send_dto,
- &iser_task->rdma_regd[ISER_DIR_OUT],
- buf_offset,
- data_seg_len);
+ /* build the tx desc */
+ iser_initialize_task_headers(task, tx_desc);
+
+ regd_buf = &iser_task->rdma_regd[ISER_DIR_OUT];
+ tx_dsg = &tx_desc->tx_sg[1];
+ tx_dsg->addr = regd_buf->reg.va + buf_offset;
+ tx_dsg->length = data_seg_len;
+ tx_dsg->lkey = regd_buf->reg.lkey;
+ tx_desc->num_sge = 2;
if (buf_offset + data_seg_len > iser_task->data[ISER_DIR_OUT].data_len) {
iser_err("Offset:%ld & DSL:%ld in Data-Out "
@@ -433,12 +405,11 @@ int iser_send_data_out(struct iscsi_conn
itt, buf_offset, data_seg_len);
- err = iser_post_send(tx_desc);
+ err = iser_post_send(iser_conn->ib_conn, tx_desc);
if (!err)
return 0;
send_data_out_error:
- iser_dto_buffs_release(send_dto);
kmem_cache_free(ig.desc_cache, tx_desc);
iser_err("conn %p failed err %d\n",conn, err);
return err;
@@ -449,11 +420,9 @@ int iser_send_control(struct iscsi_conn
{
struct iscsi_iser_conn *iser_conn = conn->dd_data;
struct iscsi_iser_task *iser_task = task->dd_data;
- struct iser_desc *mdesc = &iser_task->desc;
- struct iser_dto *send_dto = NULL;
+ struct iser_tx_desc *mdesc = &iser_task->desc;
unsigned long data_seg_len;
- int err;
- struct iser_regd_buf *regd_buf;
+ int err = 0;
struct iser_device *device;
if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
@@ -466,27 +435,24 @@ int iser_send_control(struct iscsi_conn
/* build the tx desc regd header and add it to the tx desc dto */
mdesc->type = ISCSI_TX_CONTROL;
- send_dto = &mdesc->dto;
- send_dto->task = NULL;
- iser_create_send_desc(iser_conn, mdesc);
+ iser_create_send_desc(iser_conn->ib_conn, mdesc);
device = iser_conn->ib_conn->device;
- iser_reg_single(device, send_dto->regd[0], DMA_TO_DEVICE);
-
data_seg_len = ntoh24(task->hdr->dlength);
if (data_seg_len > 0) {
- regd_buf = &mdesc->data_regd_buf;
- memset(regd_buf, 0, sizeof(struct iser_regd_buf));
- regd_buf->device = device;
- regd_buf->virt_addr = task->data;
- regd_buf->data_size = task->data_count;
- iser_reg_single(device, regd_buf,
- DMA_TO_DEVICE);
- iser_dto_add_regd_buff(send_dto, regd_buf,
- 0,
- data_seg_len);
+ struct ib_sge *tx_dsg = &mdesc->tx_sg[1];
+ if (task != conn->login_task) {
+ iser_err("data present on non login task!!!\n");
+ goto send_control_error;
+ }
+ memcpy(iser_conn->ib_conn->login_buf, task->data,
+ task->data_count);
+ tx_dsg->addr = iser_conn->ib_conn->login_dma;
+ tx_dsg->length = data_seg_len;
+ tx_dsg->lkey = device->mr->lkey;
+ mdesc->num_sge = 2;
}
if (task == conn->login_task) {
@@ -495,12 +461,11 @@ int iser_send_control(struct iscsi_conn
goto send_control_error;
}
- err = iser_post_send(mdesc);
+ err = iser_post_send(iser_conn->ib_conn, mdesc);
if (!err)
return 0;
send_control_error:
- iser_dto_buffs_release(send_dto);
iser_err("conn %p failed err %d\n",conn, err);
return err;
}
@@ -584,21 +549,20 @@ void iser_rcv_completion(struct iser_rx_
}
}
-void iser_snd_completion(struct iser_desc *tx_desc)
+void iser_snd_completion(struct iser_tx_desc *tx_desc,
+ struct iser_conn *ib_conn)
{
- struct iser_dto *dto = &tx_desc->dto;
- struct iser_conn *ib_conn = dto->ib_conn;
struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
struct iscsi_conn *conn = iser_conn->iscsi_conn;
struct iscsi_task *task;
int resume_tx = 0;
+ struct iser_device *device = ib_conn->device;
- iser_dbg("Initiator, Data sent dto=0x%p\n", dto);
-
- iser_dto_buffs_release(dto);
-
- if (tx_desc->type == ISCSI_TX_DATAOUT)
+ if (tx_desc->type == ISCSI_TX_DATAOUT) {
+ ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr,
+ ISER_HEADERS_LEN, DMA_TO_DEVICE);
kmem_cache_free(ig.desc_cache, tx_desc);
+ }
if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
ISER_QP_MAX_REQ_DTOS)
@@ -639,7 +603,6 @@ void iser_task_rdma_init(struct iscsi_is
void iser_task_rdma_finalize(struct iscsi_iser_task *iser_task)
{
- int deferred;
int is_rdma_aligned = 1;
struct iser_regd_buf *regd;
@@ -657,32 +620,17 @@ void iser_task_rdma_finalize(struct iscs
if (iser_task->dir[ISER_DIR_IN]) {
regd = &iser_task->rdma_regd[ISER_DIR_IN];
- deferred = iser_regd_buff_release(regd);
- if (deferred) {
- iser_err("%d references remain for BUF-IN rdma reg\n",
- atomic_read(®d->ref_count));
- }
+ if (regd->reg.is_fmr)
+ iser_unreg_mem(®d->reg);
}
if (iser_task->dir[ISER_DIR_OUT]) {
regd = &iser_task->rdma_regd[ISER_DIR_OUT];
- deferred = iser_regd_buff_release(regd);
- if (deferred) {
- iser_err("%d references remain for BUF-OUT rdma reg\n",
- atomic_read(®d->ref_count));
- }
+ if (regd->reg.is_fmr)
+ iser_unreg_mem(®d->reg);
}
/* if the data was unaligned, it was already unmapped and then copied */
if (is_rdma_aligned)
iser_dma_unmap_task_data(iser_task);
}
-
-void iser_dto_buffs_release(struct iser_dto *dto)
-{
- int i;
-
- for (i = 0; i < dto->regd_vector_len; i++)
- iser_regd_buff_release(dto->regd[i]);
-}
-
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -193,28 +193,8 @@ struct iser_regd_buf {
struct iser_mem_reg reg; /* memory registration info */
void *virt_addr;
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 */
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 {
@@ -223,14 +203,15 @@ enum iser_desc_type {
ISCSI_TX_DATAOUT
};
-struct iser_desc {
+struct iser_tx_desc {
struct iser_hdr iser_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;
- 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 + \
@@ -287,7 +268,7 @@ struct iscsi_iser_conn {
};
struct iscsi_iser_task {
- struct iser_desc desc;
+ struct iser_tx_desc desc;
struct iscsi_iser_conn *iser_conn;
enum iser_task_status status;
int command_sent; /* set if command sent */
@@ -295,6 +276,7 @@ struct iscsi_iser_task {
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_copy[ISER_DIRS_NUM];/* contig. copy */
+ int headers_initialized;
};
struct iser_page_vec {
@@ -346,22 +328,14 @@ void iser_rcv_completion(struct iser_rx_
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_finalize(struct iscsi_iser_task *task);
-void iser_dto_buffs_release(struct iser_dto *dto);
-
-int iser_regd_buff_release(struct iser_regd_buf *regd_buf);
-
void iser_free_rx_descriptors(struct iser_conn *ib_conn);
-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,
enum iser_data_dir cmd_dir);
@@ -381,7 +355,7 @@ void iser_unreg_mem(struct iser_mem_reg
int iser_post_recvl(struct iser_conn *ib_conn);
int iser_post_recvm(struct iser_conn *ib_conn, int count);
-int iser_post_send(struct iser_desc *tx_desc);
+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);
@@ -392,4 +366,6 @@ int iser_dma_map_task_data(struct iscsi_
enum dma_data_direction dma_dir);
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
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -128,6 +128,28 @@ static int iscsi_iser_pdu_alloc(struct i
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
* @task: iscsi task
@@ -137,17 +159,17 @@ static int iscsi_iser_pdu_alloc(struct i
static int
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;
+ if (!iser_task->headers_initialized)
+ if (iser_initialize_task_headers(task, &iser_task->desc))
+ return -ENOMEM;
+
/* mgmt task */
- if (!task->sc) {
- iser_task->desc.data = task->data;
+ if (!task->sc)
return 0;
- }
iser_task->command_sent = 0;
- iser_task->iser_conn = iser_conn;
iser_task_rdma_init(iser_task);
return 0;
}
@@ -675,7 +697,7 @@ static int __init iser_init(void)
memset(&ig, 0, sizeof(struct iser_global));
ig.desc_cache = kmem_cache_create("iser_descriptors",
- sizeof (struct iser_desc),
+ sizeof(struct iser_tx_desc),
0, SLAB_HWCACHE_ALIGN,
NULL);
if (ig.desc_cache == NULL)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_verbs.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -194,7 +194,7 @@ static int iser_create_ib_conn_res(struc
init_attr.recv_cq = device->rx_cq;
init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS;
init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
- init_attr.cap.max_send_sge = MAX_REGD_BUF_VECTOR_LEN;
+ init_attr.cap.max_send_sge = 2;
init_attr.cap.max_recv_sge = 1;
init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
init_attr.qp_type = IB_QPT_RC;
@@ -702,85 +702,36 @@ int iser_post_recvm(struct iser_conn *ib
/**
- * iser_dto_to_iov - builds IOV from a dto descriptor
- */
-static void iser_dto_to_iov(struct iser_dto *dto, struct ib_sge *iov, int iov_len)
-{
- int i;
- struct ib_sge *sge;
- struct iser_regd_buf *regd_buf;
-
- if (dto->regd_vector_len > iov_len) {
- iser_err("iov size %d too small for posting dto of len %d\n",
- iov_len, dto->regd_vector_len);
- BUG();
- }
-
- for (i = 0; i < dto->regd_vector_len; i++) {
- sge = &iov[i];
- regd_buf = dto->regd[i];
-
- sge->addr = regd_buf->reg.va;
- sge->length = regd_buf->reg.len;
- sge->lkey = regd_buf->reg.lkey;
-
- if (dto->used_sz[i] > 0) /* Adjust size */
- sge->length = dto->used_sz[i];
-
- /* offset and length should not exceed the regd buf length */
- if (sge->length + dto->offset[i] > regd_buf->reg.len) {
- iser_err("Used len:%ld + offset:%d, exceed reg.buf.len:"
- "%ld in dto:0x%p [%d], va:0x%08lX\n",
- (unsigned long)sge->length, dto->offset[i],
- (unsigned long)regd_buf->reg.len, dto, i,
- (unsigned long)sge->addr);
- BUG();
- }
-
- sge->addr += dto->offset[i]; /* Adjust offset */
- }
-}
-
-
-/**
* iser_start_send - Initiate a Send DTO operation
*
* returns 0 on success, -1 on failure
*/
-int iser_post_send(struct iser_desc *tx_desc)
+int iser_post_send(struct iser_conn *ib_conn, struct iser_tx_desc *tx_desc)
{
- int ib_ret, ret_val = 0;
+ int ib_ret;
struct ib_send_wr send_wr, *send_wr_failed;
- struct ib_sge iov[MAX_REGD_BUF_VECTOR_LEN];
- struct iser_conn *ib_conn;
- struct iser_dto *dto = &tx_desc->dto;
- ib_conn = dto->ib_conn;
-
- iser_dto_to_iov(dto, iov, MAX_REGD_BUF_VECTOR_LEN);
+ ib_dma_sync_single_for_device(ib_conn->device->ib_device,
+ tx_desc->dma_addr, ISER_HEADERS_LEN, DMA_TO_DEVICE);
send_wr.next = NULL;
send_wr.wr_id = (unsigned long)tx_desc;
- send_wr.sg_list = iov;
- send_wr.num_sge = dto->regd_vector_len;
+ send_wr.sg_list = tx_desc->tx_sg;
+ send_wr.num_sge = tx_desc->num_sge;
send_wr.opcode = IB_WR_SEND;
- send_wr.send_flags = dto->notify_enable ? IB_SEND_SIGNALED : 0;
+ send_wr.send_flags = IB_SEND_SIGNALED;
atomic_inc(&ib_conn->post_send_buf_count);
ib_ret = ib_post_send(ib_conn->qp, &send_wr, &send_wr_failed);
if (ib_ret) {
- iser_err("Failed to start SEND DTO, dto: 0x%p, IOV len: %d\n",
- dto, dto->regd_vector_len);
iser_err("ib_post_send failed, ret:%d\n", ib_ret);
atomic_dec(&ib_conn->post_send_buf_count);
- ret_val = -1;
}
-
- return ret_val;
+ return ib_ret;
}
-static void iser_handle_comp_error(struct iser_desc *desc,
+static void iser_handle_comp_error(struct iser_tx_desc *desc,
struct iser_conn *ib_conn)
{
if (desc && desc->type == ISCSI_TX_DATAOUT)
@@ -809,16 +760,16 @@ static int iser_drain_tx_cq(struct iser_
{
struct ib_cq *cq = device->tx_cq;
struct ib_wc wc;
- struct iser_desc *tx_desc;
+ struct iser_tx_desc *tx_desc;
struct iser_conn *ib_conn;
int completed_tx = 0;
while (ib_poll_cq(cq, 1, &wc) == 1) {
- tx_desc = (struct iser_desc *) (unsigned long) wc.wr_id;
+ tx_desc = (struct iser_tx_desc *) (unsigned long) wc.wr_id;
ib_conn = wc.qp->qp_context;
if (wc.status == IB_WC_SUCCESS) {
if (wc.opcode == IB_WC_SEND)
- iser_snd_completion(tx_desc);
+ iser_snd_completion(tx_desc, ib_conn);
else
iser_err("expected opcode %d got %d\n",
IB_WC_SEND, wc.opcode);
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_memory.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_memory.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_memory.c
@@ -41,62 +41,6 @@
#define ISER_KMALLOC_THRESHOLD 0x20000 /* 128K - kmalloc limit */
/**
- * Decrements the reference count for the
- * registered buffer & releases it
- *
- * returns 0 if released, 1 if deferred
- */
-int iser_regd_buff_release(struct iser_regd_buf *regd_buf)
-{
- struct ib_device *dev;
-
- if ((atomic_read(®d_buf->ref_count) == 0) ||
- atomic_dec_and_test(®d_buf->ref_count)) {
- /* if we used the dma mr, unreg is just NOP */
- if (regd_buf->reg.is_fmr)
- iser_unreg_mem(®d_buf->reg);
-
- if (regd_buf->dma_addr) {
- dev = regd_buf->device->ib_device;
- ib_dma_unmap_single(dev,
- regd_buf->dma_addr,
- regd_buf->data_size,
- regd_buf->direction);
- }
- /* else this regd buf is associated with task which we */
- /* dma_unmap_single/sg later */
- return 0;
- } else {
- iser_dbg("Release deferred, regd.buff: 0x%p\n", regd_buf);
- return 1;
- }
-}
-
-/**
- * iser_reg_single - fills registered buffer descriptor with
- * registration information
- */
-void iser_reg_single(struct iser_device *device,
- struct iser_regd_buf *regd_buf,
- enum dma_data_direction direction)
-{
- u64 dma_addr;
-
- dma_addr = ib_dma_map_single(device->ib_device,
- regd_buf->virt_addr,
- regd_buf->data_size, direction);
- BUG_ON(ib_dma_mapping_error(device->ib_device, dma_addr));
-
- regd_buf->reg.lkey = device->mr->lkey;
- regd_buf->reg.len = regd_buf->data_size;
- regd_buf->reg.va = dma_addr;
- regd_buf->reg.is_fmr = 0;
-
- regd_buf->dma_addr = dma_addr;
- regd_buf->direction = direction;
-}
-
-/**
* iser_start_rdma_unaligned_sg
*/
static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
@@ -474,9 +418,5 @@ int iser_reg_rdma_mem(struct iscsi_iser_
return err;
}
}
-
- /* take a reference on this regd buf such that it will not be released *
- * (eg in send dto completion) before we get the scsi response */
- atomic_inc(®d_buf->ref_count);
return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 06/9] ib/iser: use atomic allocations
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
` (4 preceding siblings ...)
2010-02-03 15:37 ` [PATCH 05/9] ib/iser: simplify send flow/descriptors Or Gerlitz
@ 2010-02-03 15:39 ` Or Gerlitz
2010-02-03 15:40 ` [PATCH 07/9] ib/iser: remove unnecessary connection checks Or Gerlitz
` (5 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:39 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie
Two minor flows in iser's data path still use allocations,
move them to be atomic as a preperation step towards moving
to use libiscsi passthrough flow.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
---
drivers/infiniband/ulp/iser/iser_initiator.c | 2 +-
drivers/infiniband/ulp/iser/iser_memory.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -373,7 +373,7 @@ int iser_send_data_out(struct iscsi_conn
iser_dbg("%s itt %d dseg_len %d offset %d\n",
__func__,(int)itt,(int)data_seg_len,(int)buf_offset);
- tx_desc = kmem_cache_zalloc(ig.desc_cache, GFP_NOIO);
+ tx_desc = kmem_cache_zalloc(ig.desc_cache, GFP_ATOMIC);
if (tx_desc == NULL) {
iser_err("Failed to alloc desc for post dataout\n");
return -ENOMEM;
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_memory.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_memory.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_memory.c
@@ -53,10 +53,10 @@ static int iser_start_rdma_unaligned_sg(
unsigned long cmd_data_len = data->data_len;
if (cmd_data_len > ISER_KMALLOC_THRESHOLD)
- mem = (void *)__get_free_pages(GFP_NOIO,
+ mem = (void *)__get_free_pages(GFP_ATOMIC,
ilog2(roundup_pow_of_two(cmd_data_len)) - PAGE_SHIFT);
else
- mem = kmalloc(cmd_data_len, GFP_NOIO);
+ mem = kmalloc(cmd_data_len, GFP_ATOMIC);
if (mem == NULL) {
iser_err("Failed to allocate mem size %d %d for copying sglist\n",
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 07/9] ib/iser: remove unnecessary connection checks
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
` (5 preceding siblings ...)
2010-02-03 15:39 ` [PATCH 06/9] ib/iser: use atomic allocations Or Gerlitz
@ 2010-02-03 15:40 ` Or Gerlitz
2010-02-03 15:41 ` [PATCH 08/9] ib/iser: move to use libiscsi passthrough mode Or Gerlitz
` (4 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:40 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie
remove unnecessary checks for the IB connection state and for QP
overflow, as conn state changes are reported by iser to libiscsi
and handled there. QP overflow is theoretically possible only when
unsolicited data-outs are used, its being checked and handled
by HW drivers.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
---
drivers/infiniband/ulp/iser/iscsi_iser.h | 3 --
drivers/infiniband/ulp/iser/iser_initiator.c | 38 ---------------------------
drivers/infiniband/ulp/iser/iser_verbs.c | 11 -------
3 files changed, 52 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -260,20 +260,6 @@ int iser_conn_set_full_featured_mode(str
return 0;
}
-static int
-iser_check_xmit(struct iscsi_conn *conn, void *task)
-{
- struct iscsi_iser_conn *iser_conn = conn->dd_data;
-
- if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
- ISER_QP_MAX_REQ_DTOS) {
- iser_dbg("%ld can't xmit task %p\n",jiffies,task);
- return -ENOBUFS;
- }
- return 0;
-}
-
-
/**
* iser_send_command - send command PDU
*/
@@ -289,13 +275,6 @@ int iser_send_command(struct iscsi_conn
struct scsi_cmnd *sc = task->sc;
struct iser_tx_desc *tx_desc = &iser_task->desc;
- if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
- iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
- return -EPERM;
- }
- if (iser_check_xmit(conn, task))
- return -ENOBUFS;
-
edtl = ntohl(hdr->data_length);
/* build the tx desc regd header and add it to the tx desc dto */
@@ -357,15 +336,6 @@ int iser_send_data_out(struct iscsi_conn
int err = 0;
struct ib_sge *tx_dsg;
-
- if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
- iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
- return -EPERM;
- }
-
- if (iser_check_xmit(conn, task))
- return -ENOBUFS;
-
itt = (__force uint32_t)hdr->itt;
data_seg_len = ntoh24(hdr->dlength);
buf_offset = ntohl(hdr->offset);
@@ -425,14 +395,6 @@ int iser_send_control(struct iscsi_conn
int err = 0;
struct iser_device *device;
- if (!iser_conn_state_comp(iser_conn->ib_conn, ISER_CONN_UP)) {
- iser_err("Failed to send, conn: 0x%p is not up\n", iser_conn->ib_conn);
- return -EPERM;
- }
-
- if (iser_check_xmit(conn, task))
- return -ENOBUFS;
-
/* build the tx desc regd header and add it to the tx desc dto */
mdesc->type = ISCSI_TX_CONTROL;
iser_create_send_desc(iser_conn->ib_conn, mdesc);
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -357,9 +357,6 @@ int iser_post_recvl(struct iser_conn *i
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,
struct iser_data_buf *data,
enum iser_data_dir iser_dir,
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_verbs.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -300,17 +300,6 @@ static void iser_device_try_release(stru
mutex_unlock(&ig.device_list_mutex);
}
-int iser_conn_state_comp(struct iser_conn *ib_conn,
- enum iser_ib_conn_state comp)
-{
- int ret;
-
- spin_lock_bh(&ib_conn->lock);
- ret = (ib_conn->state == comp);
- spin_unlock_bh(&ib_conn->lock);
- return ret;
-}
-
static int iser_conn_state_comp_exch(struct iser_conn *ib_conn,
enum iser_ib_conn_state comp,
enum iser_ib_conn_state exch)
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 08/9] ib/iser: move to use libiscsi passthrough mode
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
` (6 preceding siblings ...)
2010-02-03 15:40 ` [PATCH 07/9] ib/iser: remove unnecessary connection checks Or Gerlitz
@ 2010-02-03 15:41 ` Or Gerlitz
[not found] ` <Pine.LNX.4.64.1002031740540.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
2010-02-03 15:42 ` [PATCH 08/10] ib/iser: remove redundant locking from command response flow Or Gerlitz
` (3 subsequent siblings)
11 siblings, 1 reply; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:41 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie
The libiscsi passthrough mode invokes the transport xmit calls directly
without passing through an internal queue, now when the "cant_sleep"
prerequisite of iscsi_alloc_session is met, move to use it. Since the
libibscsi queue isn't used in passthrough mode, the code that schedules
the xmitworker is removed.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
---
drivers/infiniband/ulp/iser/iscsi_iser.c | 2 +-
drivers/infiniband/ulp/iser/iser_initiator.c | 12 ------------
2 files changed, 1 insertion(+), 13 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -423,7 +423,7 @@ iscsi_iser_session_create(struct iscsi_e
struct Scsi_Host *shost;
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)
return NULL;
shost->transportt = iscsi_iser_scsi_transport;
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -514,10 +514,7 @@ void iser_rcv_completion(struct iser_rx_
void iser_snd_completion(struct iser_tx_desc *tx_desc,
struct iser_conn *ib_conn)
{
- struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
- struct iscsi_conn *conn = iser_conn->iscsi_conn;
struct iscsi_task *task;
- int resume_tx = 0;
struct iser_device *device = ib_conn->device;
if (tx_desc->type == ISCSI_TX_DATAOUT) {
@@ -526,17 +523,8 @@ void iser_snd_completion(struct iser_tx_
kmem_cache_free(ig.desc_cache, tx_desc);
}
- if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
- ISER_QP_MAX_REQ_DTOS)
- resume_tx = 1;
-
atomic_dec(&ib_conn->post_send_buf_count);
- if (resume_tx) {
- iser_dbg("%ld resuming tx\n",jiffies);
- iscsi_conn_queue_work(conn);
- }
-
if (tx_desc->type == ISCSI_TX_CONTROL) {
/* this arithmetic is legal by libiscsi dd_data allocation */
task = (void *) ((long)(void *)tx_desc -
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 08/10] ib/iser: remove redundant locking from command response flow
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
` (7 preceding siblings ...)
2010-02-03 15:41 ` [PATCH 08/9] ib/iser: move to use libiscsi passthrough mode Or Gerlitz
@ 2010-02-03 15:42 ` Or Gerlitz
2010-02-03 15:44 ` [PATCH 09/9] remove redundant locking from iser scsi " Or Gerlitz
` (2 subsequent siblings)
11 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:42 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie
currently iser recv completion flow takes the session lock twice.
optimize it to avoid the first one by letting iser_task_rdma_finalize()
be called only from the cleanup_task callback invoked by iscsi_free_task,
thus reducing the contention on the session lock between the scsi
command submission to the scsi command completion flows.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
Reviewed-by: Mike Christie <michaelc-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>
---
drivers/infiniband/ulp/iser/iser_initiator.c | 25 -------------------------
1 file changed, 25 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -440,10 +440,7 @@ void iser_rcv_completion(struct iser_rx_
struct iser_conn *ib_conn)
{
struct iscsi_iser_conn *conn = ib_conn->iser_conn;
- struct iscsi_task *task;
- struct iscsi_iser_task *iser_task;
struct iscsi_hdr *hdr;
- unsigned char opcode;
u64 rx_dma;
int rx_buflen, outstanding, count, err;
@@ -464,28 +461,6 @@ void iser_rcv_completion(struct iser_rx_
iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
hdr->itt, (int)(rx_xfer_len - ISER_HEADERS_LEN));
- opcode = hdr->opcode & ISCSI_OPCODE_MASK;
-
- if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
- spin_lock(&conn->iscsi_conn->session->lock);
- task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
- if (task)
- __iscsi_get_task(task);
- spin_unlock(&conn->iscsi_conn->session->lock);
-
- if (!task)
- iser_err("itt can't be matched to task!!! "
- "conn %p opcode %d itt %d\n",
- conn->iscsi_conn, opcode, hdr->itt);
- else {
- iser_task = task->dd_data;
- iser_dbg("itt %d task %p\n",hdr->itt, task);
- iser_task->status = ISER_TASK_STATUS_COMPLETED;
- iser_task_rdma_finalize(iser_task);
- iscsi_put_task(task);
- }
- }
-
iscsi_iser_recv(conn->iscsi_conn, hdr,
rx_desc->data, rx_xfer_len - ISER_HEADERS_LEN);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 09/9] remove redundant locking from iser scsi command response flow
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
` (8 preceding siblings ...)
2010-02-03 15:42 ` [PATCH 08/10] ib/iser: remove redundant locking from command response flow Or Gerlitz
@ 2010-02-03 15:44 ` Or Gerlitz
2010-02-03 16:10 ` [PATCH 0/8] ib/iser: major face lift of the data path code Bart Van Assche
2010-02-03 16:11 ` Bart Van Assche
11 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-03 15:44 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma, Mike Christie
currently iser recv completion flow takes the session lock twice.
optimize it to avoid the first one by letting iser_task_rdma_finalize()
be called only from the cleanup_task callback invoked by iscsi_free_task,
thus reducing the contention on the session lock between the scsi
command submission to the scsi command completion flows.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
Reviewed-by: Mike Christie <michaelc-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>
---
re-sending, with a corrected subjest line
drivers/infiniband/ulp/iser/iser_initiator.c | 25 -------------------------
1 file changed, 25 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -440,10 +440,7 @@ void iser_rcv_completion(struct iser_rx_
struct iser_conn *ib_conn)
{
struct iscsi_iser_conn *conn = ib_conn->iser_conn;
- struct iscsi_task *task;
- struct iscsi_iser_task *iser_task;
struct iscsi_hdr *hdr;
- unsigned char opcode;
u64 rx_dma;
int rx_buflen, outstanding, count, err;
@@ -464,28 +461,6 @@ void iser_rcv_completion(struct iser_rx_
iser_dbg("op 0x%x itt 0x%x dlen %d\n", hdr->opcode,
hdr->itt, (int)(rx_xfer_len - ISER_HEADERS_LEN));
- opcode = hdr->opcode & ISCSI_OPCODE_MASK;
-
- if (opcode == ISCSI_OP_SCSI_CMD_RSP) {
- spin_lock(&conn->iscsi_conn->session->lock);
- task = iscsi_itt_to_ctask(conn->iscsi_conn, hdr->itt);
- if (task)
- __iscsi_get_task(task);
- spin_unlock(&conn->iscsi_conn->session->lock);
-
- if (!task)
- iser_err("itt can't be matched to task!!! "
- "conn %p opcode %d itt %d\n",
- conn->iscsi_conn, opcode, hdr->itt);
- else {
- iser_task = task->dd_data;
- iser_dbg("itt %d task %p\n",hdr->itt, task);
- iser_task->status = ISER_TASK_STATUS_COMPLETED;
- iser_task_rdma_finalize(iser_task);
- iscsi_put_task(task);
- }
- }
-
iscsi_iser_recv(conn->iscsi_conn, hdr,
rx_desc->data, rx_xfer_len - ISER_HEADERS_LEN);
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/8] ib/iser: major face lift of the data path code
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
` (9 preceding siblings ...)
2010-02-03 15:44 ` [PATCH 09/9] remove redundant locking from iser scsi " Or Gerlitz
@ 2010-02-03 16:10 ` Bart Van Assche
2010-02-03 16:11 ` Bart Van Assche
11 siblings, 0 replies; 21+ messages in thread
From: Bart Van Assche @ 2010-02-03 16:10 UTC (permalink / raw)
To: open-iscsi-/JYPxA39Uh5TLH3MbocFFw
Cc: Roland Dreier, linux-rdma, Mike Christie
[-- Attachment #1: Type: text/plain, Size: 1601 bytes --]
On Wed, Feb 3, 2010 at 4:30 PM, Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org> wrote:
> The following patch set removes some in efficiencies in the iser data path
> through simplification and reducing the amount of code, using less atomic
> operations, avoiding TX interrupts, moving to iscsi passthrough mode,
> etc. I did my best to build it as a sequence of patches and not as one
> big re-write, to allow for better debugging (e.g bisection) and tuning.
>
> Or.
>
> [PATCH 01/9] ib/iser: revert commit bba7ebb "avoid recv buffer exhaustion"
> [PATCH 02/9] ib/iser: new recv buffer posting logic
> [PATCH 03/9] ib/iser: remove atomic counter for posted recv buffers
> [PATCH 04/9] ib/iser: use different CQ for send completions
> [PATCH 05/9] ib/iser: simplify send flow/descriptors
> [PATCH 06/9] ib/iser: use atomic allocations
> [PATCH 07/9] ib/iser: remove unnecessary connection checks
> [PATCH 08/9] ib/iser: move to use libiscsi passthrough mode
> [PATCH 09/9] ib/iser: remove redundant locking from iser scsi command
> response flow
>
Sounds really interesting. Do you have numbers available about how much
these patches improve throughput or decrease latency ?
Bart.
--
You received this message because you are subscribed to the Google Groups "open-iscsi" group.
To post to this group, send email to open-iscsi-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to open-iscsi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.
[-- Attachment #2: Type: text/html, Size: 1959 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/8] ib/iser: major face lift of the data path code
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
` (10 preceding siblings ...)
2010-02-03 16:10 ` [PATCH 0/8] ib/iser: major face lift of the data path code Bart Van Assche
@ 2010-02-03 16:11 ` Bart Van Assche
[not found] ` <e2e108261002030811r5c740d6fr4cc055702a88aa50-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
11 siblings, 1 reply; 21+ messages in thread
From: Bart Van Assche @ 2010-02-03 16:11 UTC (permalink / raw)
To: open-iscsi-/JYPxA39Uh5TLH3MbocFFw
Cc: Roland Dreier, linux-rdma, Mike Christie
On Wed, Feb 3, 2010 at 4:30 PM, Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org> wrote:
>
> The following patch set removes some in efficiencies in the iser data path
> through simplification and reducing the amount of code, using less atomic
> operations, avoiding TX interrupts, moving to iscsi passthrough mode,
> etc. I did my best to build it as a sequence of patches and not as one
> big re-write, to allow for better debugging (e.g bisection) and tuning.
Sounds really interesting. Do you have numbers available about how
much these patches improve throughput or decrease latency ?
Bart.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 08/9] ib/iser: move to use libiscsi passthrough mode
[not found] ` <Pine.LNX.4.64.1002031740540.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
@ 2010-02-03 21:32 ` Mike Christie
[not found] ` <4B69EB5A.4050301-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>
0 siblings, 1 reply; 21+ messages in thread
From: Mike Christie @ 2010-02-03 21:32 UTC (permalink / raw)
To: Or Gerlitz; +Cc: Roland Dreier, linux-rdma
On 02/03/2010 09:41 AM, Or Gerlitz wrote:
> @@ -526,17 +523,8 @@ void iser_snd_completion(struct iser_tx_
> kmem_cache_free(ig.desc_cache, tx_desc);
> }
>
> - if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
> - ISER_QP_MAX_REQ_DTOS)
> - resume_tx = 1;
> -
> atomic_dec(&ib_conn->post_send_buf_count);
>
> - if (resume_tx) {
> - iser_dbg("%ld resuming tx\n",jiffies);
> - iscsi_conn_queue_work(conn);
> - }
What prevents the problem this code was handling from coming up now? Are
you now preallocating enough resources, or are you returning
-ENOMEM/-ENOBUFS from the init_task/xmit_task callouts so the scsi layer
is now requeueing the IO?
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 08/9] ib/iser: move to use libiscsi passthrough mode
[not found] ` <4B69EB5A.4050301-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>
@ 2010-02-04 11:21 ` Or Gerlitz
[not found] ` <4B6AADD4.2050607-hKgKHo2Ms0FWk0Htik3J/w@public.gmane.org>
0 siblings, 1 reply; 21+ messages in thread
From: Or Gerlitz @ 2010-02-04 11:21 UTC (permalink / raw)
To: Mike Christie; +Cc: Roland Dreier, linux-rdma
Mike Christie wrote:
> What prevents the problem this code was handling from coming up now? Are
> you now preallocating enough resources, or are you returning
> -ENOMEM/-ENOBUFS from the init_task/xmit_task callouts so the scsi layer
> is now requeueing the IO?
Basically before/after this change we preallocate enough resources (namely
the size of the QP TX ring), and hitting this error as of over-flow is kind
of impossible in practice. Still, there was a problem here which I fixed and
will post as V2 (below).
[PATCH V2 08/9] ib/iser: move to use libiscsi passthrough mode
The libiscsi passthrough mode invokes the transport xmit calls directly
without first going through an internal queue as done in the other mode
which uses a queue and a xmitworker thread. Now when the "cant_sleep"
prerequisite of iscsi_host_alloc is met, move to use it. Handling xmit
errors is now done by the passthrough flow of libiscsi. Since the
queue/worker aren't used in this mode, the code that schedules the
xmitworker is removed.
Signed-off-by: Or Gerlitz <ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
---
changes from V1:
- remove calls to iscsi_conn_failure which are under now both buggy and not needed, instead
return errors to libiscsi (e.g iscsi_queuecommand, __iscsi_conn_send_pdu)
- enhance/fix the two debug prints and the change log
I tested the error flow by instrumenting the xmit code to inject synthetic
failures from time to time and things are working just great, see that the command
with ITT 0x71 is failed by iser, then xmitted again, completed fine, etc.
> session2: iscsi_prep_scsi_cmd_pdu iscsi prep [read cid 0 sc ffff8802137a8100 cdb 0x28 itt 0x71 len 4096 bidi_len 0 cmdsn 39015 win 129]
> iser: iscsi_iser_task_xmit:ctask xmit [cid 0 itt 0x71]
> iser: iser_reg_rdma_mem:PHYSICAL Mem.register: lkey: 0x300422AA rkey: 0x300422AA va: 0x213540000 sz: 4096]
> iser: iser_prepare_read_cmd:Cmd itt:113 READ tags RKEY:0X300422AA VA:0X213540000
> iser: iser_send_command:XXXX emulating command failure with -ENOMEM
> iser: iser_send_command:conn ffff880218d3d198 failed task->itt 113 err -12
> session2: iscsi_complete_task complete task itt 0x71 state 3 sc ffff8802137a8100
> session2: iscsi_free_task freeing task itt 0x71 state 1 sc ffff8802137a8100
> session2: iscsi_queuecommand cmd 0x28 rejected (10)
> session2: iscsi_prep_scsi_cmd_pdu iscsi prep [read cid 0 sc ffff8802137a8100 cdb 0x28 itt 0x72 len 4096 bidi_len 0 cmdsn 39015 win 129]
> iser: iscsi_iser_task_xmit:ctask xmit [cid 0 itt 0x72]
> iser: iser_reg_rdma_mem:PHYSICAL Mem.register: lkey: 0x300422AA rkey: 0x300422AA va: 0x213540000 sz: 4096]
> iser: iser_prepare_read_cmd:Cmd itt:114 READ tags RKEY:0X300422AA VA:0X213540000
> iser: iser_rcv_completion:op 0x21 itt 0x72 dlen 0
> session2: __iscsi_complete_pdu [op 0x21 cid 0 itt 0x72 len 0]
> session2: iscsi_scsi_cmd_rsp cmd rsp done [sc ffff8802137a8100 res 0 itt 0x72]
> session2: iscsi_complete_task complete task itt 0x72 state 3 sc ffff8802137a8100
> session2: iscsi_free_task freeing task itt 0x72 state 1 sc ffff8802137a8100
drivers/infiniband/ulp/iser/iscsi_iser.c | 11 +++--------
drivers/infiniband/ulp/iser/iser_initiator.c | 12 ------------
2 files changed, 3 insertions(+), 20 deletions(-)
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -190,7 +190,7 @@ iscsi_iser_mtask_xmit(struct iscsi_conn
{
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);
@@ -200,9 +200,6 @@ iscsi_iser_mtask_xmit(struct iscsi_conn
* - if yes, the task is recycled at iscsi_complete_pdu
* - if no, the task is recycled at iser_snd_completion
*/
- if (error && error != -ENOBUFS)
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-
return error;
}
@@ -254,7 +251,7 @@ iscsi_iser_task_xmit(struct iscsi_task *
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);
/* Send the cmd PDU */
@@ -270,8 +267,6 @@ iscsi_iser_task_xmit(struct iscsi_task *
error = iscsi_iser_task_xmit_unsol_data(conn, task);
iscsi_iser_task_xmit_exit:
- if (error && error != -ENOBUFS)
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
return error;
}
@@ -423,7 +418,7 @@ iscsi_iser_session_create(struct iscsi_e
struct Scsi_Host *shost;
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)
return NULL;
shost->transportt = iscsi_iser_scsi_transport;
Index: linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
===================================================================
--- linux-2.6.33-rc4.orig/drivers/infiniband/ulp/iser/iser_initiator.c
+++ linux-2.6.33-rc4/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -514,10 +514,7 @@ void iser_rcv_completion(struct iser_rx_
void iser_snd_completion(struct iser_tx_desc *tx_desc,
struct iser_conn *ib_conn)
{
- struct iscsi_iser_conn *iser_conn = ib_conn->iser_conn;
- struct iscsi_conn *conn = iser_conn->iscsi_conn;
struct iscsi_task *task;
- int resume_tx = 0;
struct iser_device *device = ib_conn->device;
if (tx_desc->type == ISCSI_TX_DATAOUT) {
@@ -526,17 +523,8 @@ void iser_snd_completion(struct iser_tx_
kmem_cache_free(ig.desc_cache, tx_desc);
}
- if (atomic_read(&iser_conn->ib_conn->post_send_buf_count) ==
- ISER_QP_MAX_REQ_DTOS)
- resume_tx = 1;
-
atomic_dec(&ib_conn->post_send_buf_count);
- if (resume_tx) {
- iser_dbg("%ld resuming tx\n",jiffies);
- iscsi_conn_queue_work(conn);
- }
-
if (tx_desc->type == ISCSI_TX_CONTROL) {
/* this arithmetic is legal by libiscsi dd_data allocation */
task = (void *) ((long)(void *)tx_desc -
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 05/9] ib/iser: simplify send flow/descriptors
[not found] ` <Pine.LNX.4.64.1002031737090.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
@ 2010-02-04 11:23 ` Or Gerlitz
0 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-04 11:23 UTC (permalink / raw)
To: Roland Dreier; +Cc: linux-rdma
Or Gerlitz wrote:
> Simplify and shrink the logic/code used for the send descriptors.
> Changes include removal of struct iser_dto which is unnecessary
> abstraction, use struct iser_regd_buf only for handling SCSI commands,
> use dma_sync instead of dma_map/unmap, etc.
it turns out that bunch of white-spaces slipped into this patch, will fix in V2
Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/8] ib/iser: major face lift of the data path code
[not found] ` <e2e108261002030811r5c740d6fr4cc055702a88aa50-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2010-02-04 14:21 ` Or Gerlitz
[not found] ` <4B6AD7D5.7030204-hKgKHo2Ms0FWk0Htik3J/w@public.gmane.org>
0 siblings, 1 reply; 21+ messages in thread
From: Or Gerlitz @ 2010-02-04 14:21 UTC (permalink / raw)
To: Bart Van Assche; +Cc: Roland Dreier, linux-rdma, Mike Christie, Yaron Haviv
Bart Van Assche wrote:
> Sounds really interesting. Do you have numbers available about how
> much these patches improve throughput or decrease latency ?
Yes, generally speaking after the patches the initiator peaks to about 300-400K IOPS
with latency under such load being 20-30us and before the patches the initiator was
doing upto 200K IOPS with the latency under such load being 50-100us, see some data
I got today on mytest bed. Being focused on the initiator, I was using a "NULL device"
at the target side.
AFTER
r b swpd free buff cache si so bi bo in cs us sy id wa st
11 11 0 6212936 260552 367356 0 0 308671 0 285596 492842 4 64 0 31 0
7 13 0 6212936 260552 367356 0 0 309628 24 285138 496537 5 61 0 33 0
10 12 0 6212936 260552 367356 0 0 308222 0 277868 489261 4 65 0 30 0
8 13 0 6212936 260552 367356 0 0 310724 0 282151 493868 4 67 0 29 0
12 11 0 6212936 260552 367356 0 0 308209 0 278753 489797 5 66 0 29 0
Linux 2.6.33-rc4 (cto-1) 02/04/2010
avg-cpu: %user %nice %system %iowait %steal %idle
4.62 0.00 66.29 28.71 0.00 0.37
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sdd 0.00 0.00 88905.94 0.00 177811.88 0.00 2.00 2.82 0.03 0.01 98.61
sdf 0.00 0.00 64021.78 0.00 128045.54 0.00 2.00 2.55 0.04 0.02 96.24
sdh 0.00 0.00 88922.77 0.00 177845.54 0.00 2.00 2.85 0.03 0.01 99.01
sdj 0.00 0.00 64662.38 0.00 129324.75 0.00 2.00 2.69 0.04 0.02 97.82
BEFORE
r b swpd free buff cache si so bi bo in cs us sy id wa st
6 14 0 6211804 260684 368584 0 0 195551 0 195997 557463 3 56 4 37 0
7 13 0 6211804 260684 368584 0 0 191347 0 192311 525823 3 58 3 36 0
6 15 0 6211804 260692 368584 0 0 187135 16 190875 503739 3 58 3 35 0
8 14 0 6211804 260692 368584 0 0 193745 0 193921 556821 3 55 4 38 0
8 16 0 6211804 260692 368584 0 0 191233 0 191549 536499 3 58 4 35 0
Linux 2.6.33-rc4 (cto-1) 02/04/2010
avg-cpu: %user %nice %system %iowait %steal %idle
2.24 0.00 58.16 35.87 0.00 3.74
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sdd 0.00 0.00 33964.00 0.00 67928.00 0.00 2.00 3.36 0.10 0.03 100.00
sdf 0.00 0.00 33456.00 0.00 66912.00 0.00 2.00 3.34 0.10 0.03 99.60
sdh 0.00 0.00 63176.00 0.00 126352.00 0.00 2.00 3.40 0.05 0.02 100.00
sdj 0.00 0.00 62973.00 0.00 125946.00 0.00 2.00 3.38 0.05 0.02 100.40
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 08/9] ib/iser: move to use libiscsi passthrough mode
[not found] ` <4B6AADD4.2050607-hKgKHo2Ms0FWk0Htik3J/w@public.gmane.org>
@ 2010-02-04 17:27 ` Mike Christie
0 siblings, 0 replies; 21+ messages in thread
From: Mike Christie @ 2010-02-04 17:27 UTC (permalink / raw)
To: Or Gerlitz; +Cc: Roland Dreier, linux-rdma
On 02/04/2010 05:21 AM, Or Gerlitz wrote:
>
> [PATCH V2 08/9] ib/iser: move to use libiscsi passthrough mode
>
> The libiscsi passthrough mode invokes the transport xmit calls directly
> without first going through an internal queue as done in the other mode
> which uses a queue and a xmitworker thread. Now when the "cant_sleep"
> prerequisite of iscsi_host_alloc is met, move to use it. Handling xmit
> errors is now done by the passthrough flow of libiscsi. Since the
> queue/worker aren't used in this mode, the code that schedules the
> xmitworker is removed.
>
> Signed-off-by: Or Gerlitz<ogerlitz-smomgflXvOZWk0Htik3J/w@public.gmane.org>
>
> ---
>
> changes from V1:
>
> - remove calls to iscsi_conn_failure which are under now both buggy and not needed, instead
> return errors to libiscsi (e.g iscsi_queuecommand, __iscsi_conn_send_pdu)
> - enhance/fix the two debug prints and the change log
>
Looks ok.
Reviewed-by: Mike Christie <michaelc-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/8] ib/iser: major face lift of the data path code
[not found] ` <4B6AD7D5.7030204-hKgKHo2Ms0FWk0Htik3J/w@public.gmane.org>
@ 2010-02-05 12:18 ` Vladislav Bolkhovitin
[not found] ` <4B6C0C93.2090107-d+Crzxg7Rs0@public.gmane.org>
2010-02-05 12:29 ` Vladislav Bolkhovitin
1 sibling, 1 reply; 21+ messages in thread
From: Vladislav Bolkhovitin @ 2010-02-05 12:18 UTC (permalink / raw)
To: Or Gerlitz
Cc: Bart Van Assche, Roland Dreier, linux-rdma, Mike Christie,
Yaron Haviv
Or Gerlitz, on 02/04/2010 05:21 PM wrote:
> Bart Van Assche wrote:
>> Sounds really interesting. Do you have numbers available about how
>> much these patches improve throughput or decrease latency ?
>
> Yes, generally speaking after the patches the initiator peaks to about 300-400K IOPS
> with latency under such load being 20-30us and before the patches the initiator was
> doing upto 200K IOPS with the latency under such load being 50-100us
From where did you get those latency numbers? I can estimate only IOPS
numbers from your results.
>, see some data
> I got today on mytest bed. Being focused on the initiator, I was using a "NULL device"
> at the target side.
>
> AFTER
>
> r b swpd free buff cache si so bi bo in cs us sy id wa st
> 11 11 0 6212936 260552 367356 0 0 308671 0 285596 492842 4 64 0 31 0
> 7 13 0 6212936 260552 367356 0 0 309628 24 285138 496537 5 61 0 33 0
> 10 12 0 6212936 260552 367356 0 0 308222 0 277868 489261 4 65 0 30 0
> 8 13 0 6212936 260552 367356 0 0 310724 0 282151 493868 4 67 0 29 0
> 12 11 0 6212936 260552 367356 0 0 308209 0 278753 489797 5 66 0 29 0
>
> Linux 2.6.33-rc4 (cto-1) 02/04/2010
>
> avg-cpu: %user %nice %system %iowait %steal %idle
> 4.62 0.00 66.29 28.71 0.00 0.37
>
> Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
> sdd 0.00 0.00 88905.94 0.00 177811.88 0.00 2.00 2.82 0.03 0.01 98.61
> sdf 0.00 0.00 64021.78 0.00 128045.54 0.00 2.00 2.55 0.04 0.02 96.24
> sdh 0.00 0.00 88922.77 0.00 177845.54 0.00 2.00 2.85 0.03 0.01 99.01
> sdj 0.00 0.00 64662.38 0.00 129324.75 0.00 2.00 2.69 0.04 0.02 97.82
>
> BEFORE
>
> r b swpd free buff cache si so bi bo in cs us sy id wa st
> 6 14 0 6211804 260684 368584 0 0 195551 0 195997 557463 3 56 4 37 0
> 7 13 0 6211804 260684 368584 0 0 191347 0 192311 525823 3 58 3 36 0
> 6 15 0 6211804 260692 368584 0 0 187135 16 190875 503739 3 58 3 35 0
> 8 14 0 6211804 260692 368584 0 0 193745 0 193921 556821 3 55 4 38 0
> 8 16 0 6211804 260692 368584 0 0 191233 0 191549 536499 3 58 4 35 0
>
> Linux 2.6.33-rc4 (cto-1) 02/04/2010
>
> avg-cpu: %user %nice %system %iowait %steal %idle
> 2.24 0.00 58.16 35.87 0.00 3.74
>
> Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
> sdd 0.00 0.00 33964.00 0.00 67928.00 0.00 2.00 3.36 0.10 0.03 100.00
> sdf 0.00 0.00 33456.00 0.00 66912.00 0.00 2.00 3.34 0.10 0.03 99.60
> sdh 0.00 0.00 63176.00 0.00 126352.00 0.00 2.00 3.40 0.05 0.02 100.00
> sdj 0.00 0.00 62973.00 0.00 125946.00 0.00 2.00 3.38 0.05 0.02 100.40
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/8] ib/iser: major face lift of the data path code
[not found] ` <4B6AD7D5.7030204-hKgKHo2Ms0FWk0Htik3J/w@public.gmane.org>
2010-02-05 12:18 ` Vladislav Bolkhovitin
@ 2010-02-05 12:29 ` Vladislav Bolkhovitin
1 sibling, 0 replies; 21+ messages in thread
From: Vladislav Bolkhovitin @ 2010-02-05 12:29 UTC (permalink / raw)
To: Or Gerlitz
Cc: Bart Van Assche, Roland Dreier, linux-rdma, Mike Christie,
Yaron Haviv
Or Gerlitz, on 02/04/2010 05:21 PM wrote:
> Bart Van Assche wrote:
>> Sounds really interesting. Do you have numbers available about how
>> much these patches improve throughput or decrease latency ?
>
> Yes, generally speaking after the patches the initiator peaks to about 300-400K IOPS
> with latency under such load being 20-30us and before the patches the initiator was
> doing upto 200K IOPS with the latency under such load being 50-100us, see some data
> I got today on mytest bed. Being focused on the initiator, I was using a "NULL device"
> at the target side.
Also, what kind of test did you do?
> AFTER
>
> r b swpd free buff cache si so bi bo in cs us sy id wa st
> 11 11 0 6212936 260552 367356 0 0 308671 0 285596 492842 4 64 0 31 0
> 7 13 0 6212936 260552 367356 0 0 309628 24 285138 496537 5 61 0 33 0
> 10 12 0 6212936 260552 367356 0 0 308222 0 277868 489261 4 65 0 30 0
> 8 13 0 6212936 260552 367356 0 0 310724 0 282151 493868 4 67 0 29 0
> 12 11 0 6212936 260552 367356 0 0 308209 0 278753 489797 5 66 0 29 0
>
> Linux 2.6.33-rc4 (cto-1) 02/04/2010
>
> avg-cpu: %user %nice %system %iowait %steal %idle
> 4.62 0.00 66.29 28.71 0.00 0.37
>
> Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
> sdd 0.00 0.00 88905.94 0.00 177811.88 0.00 2.00 2.82 0.03 0.01 98.61
> sdf 0.00 0.00 64021.78 0.00 128045.54 0.00 2.00 2.55 0.04 0.02 96.24
> sdh 0.00 0.00 88922.77 0.00 177845.54 0.00 2.00 2.85 0.03 0.01 99.01
> sdj 0.00 0.00 64662.38 0.00 129324.75 0.00 2.00 2.69 0.04 0.02 97.82
>
> BEFORE
>
> r b swpd free buff cache si so bi bo in cs us sy id wa st
> 6 14 0 6211804 260684 368584 0 0 195551 0 195997 557463 3 56 4 37 0
> 7 13 0 6211804 260684 368584 0 0 191347 0 192311 525823 3 58 3 36 0
> 6 15 0 6211804 260692 368584 0 0 187135 16 190875 503739 3 58 3 35 0
> 8 14 0 6211804 260692 368584 0 0 193745 0 193921 556821 3 55 4 38 0
> 8 16 0 6211804 260692 368584 0 0 191233 0 191549 536499 3 58 4 35 0
>
> Linux 2.6.33-rc4 (cto-1) 02/04/2010
>
> avg-cpu: %user %nice %system %iowait %steal %idle
> 2.24 0.00 58.16 35.87 0.00 3.74
>
> Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
> sdd 0.00 0.00 33964.00 0.00 67928.00 0.00 2.00 3.36 0.10 0.03 100.00
> sdf 0.00 0.00 33456.00 0.00 66912.00 0.00 2.00 3.34 0.10 0.03 99.60
> sdh 0.00 0.00 63176.00 0.00 126352.00 0.00 2.00 3.40 0.05 0.02 100.00
> sdj 0.00 0.00 62973.00 0.00 125946.00 0.00 2.00 3.38 0.05 0.02 100.40
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 0/8] ib/iser: major face lift of the data path code
[not found] ` <4B6C0C93.2090107-d+Crzxg7Rs0@public.gmane.org>
@ 2010-02-07 14:51 ` Or Gerlitz
0 siblings, 0 replies; 21+ messages in thread
From: Or Gerlitz @ 2010-02-07 14:51 UTC (permalink / raw)
To: Vladislav Bolkhovitin
Cc: Bart Van Assche, Roland Dreier, linux-rdma, Mike Christie,
Yaron Haviv
Vladislav Bolkhovitin wrote:
> Or Gerlitz wrote:
> From where did you get those latency numbers?
read iostat(8), you'll see that await is "The average time (in milliseconds)
for I/O requests issued to the device to be served"
> what kind of test did you do?
I connected a Linux box through iser to a target exposing four "NULL luns",
i.e luns which are not backed by real storage. I run four copies of disktest
each over a different lun, where each was reading 1k blocks, etc.
Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2010-02-07 14:51 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-03 15:30 [PATCH 0/8] ib/iser: major face lift of the data path code Or Gerlitz
[not found] ` <Pine.LNX.4.64.1002031721280.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
2010-02-03 15:31 ` [PATCH 01/9] ib/iser: revert commit bba7ebb "avoid recv buffer exhaustion" Or Gerlitz
2010-02-03 15:33 ` [PATCH 02/9] ib/iser: new recv buffer posting logic Or Gerlitz
2010-02-03 15:35 ` [PATCH 03/9] ib/iser: remove atomic counter for posted recv buffers Or Gerlitz
2010-02-03 15:36 ` [PATCH 04/9] ib/iser: use different CQ for send completions Or Gerlitz
2010-02-03 15:37 ` [PATCH 05/9] ib/iser: simplify send flow/descriptors Or Gerlitz
[not found] ` <Pine.LNX.4.64.1002031737090.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
2010-02-04 11:23 ` Or Gerlitz
2010-02-03 15:39 ` [PATCH 06/9] ib/iser: use atomic allocations Or Gerlitz
2010-02-03 15:40 ` [PATCH 07/9] ib/iser: remove unnecessary connection checks Or Gerlitz
2010-02-03 15:41 ` [PATCH 08/9] ib/iser: move to use libiscsi passthrough mode Or Gerlitz
[not found] ` <Pine.LNX.4.64.1002031740540.11944-aDiYczhfhVLdX2U7gxhm1tBPR1lH4CV8@public.gmane.org>
2010-02-03 21:32 ` Mike Christie
[not found] ` <4B69EB5A.4050301-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>
2010-02-04 11:21 ` Or Gerlitz
[not found] ` <4B6AADD4.2050607-hKgKHo2Ms0FWk0Htik3J/w@public.gmane.org>
2010-02-04 17:27 ` Mike Christie
2010-02-03 15:42 ` [PATCH 08/10] ib/iser: remove redundant locking from command response flow Or Gerlitz
2010-02-03 15:44 ` [PATCH 09/9] remove redundant locking from iser scsi " Or Gerlitz
2010-02-03 16:10 ` [PATCH 0/8] ib/iser: major face lift of the data path code Bart Van Assche
2010-02-03 16:11 ` Bart Van Assche
[not found] ` <e2e108261002030811r5c740d6fr4cc055702a88aa50-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-02-04 14:21 ` Or Gerlitz
[not found] ` <4B6AD7D5.7030204-hKgKHo2Ms0FWk0Htik3J/w@public.gmane.org>
2010-02-05 12:18 ` Vladislav Bolkhovitin
[not found] ` <4B6C0C93.2090107-d+Crzxg7Rs0@public.gmane.org>
2010-02-07 14:51 ` Or Gerlitz
2010-02-05 12:29 ` Vladislav Bolkhovitin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).