aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorEddie Wai <eddie.wai@broadcom.com>2011-05-16 14:13:20 -0400
committerJames Bottomley <jbottomley@parallels.com>2011-05-24 12:41:10 -0400
commit9ae58e144df1a4ecc91dcd9eea5a3f4a6d13b5fc (patch)
treecc6ef10a0aa8d4a13aebc7d07bede9eba51069fa /drivers/scsi
parentd5307a078bb0288945c900c6f4a2fd77ba6d0817 (diff)
[SCSI] bnx2i: Optimized the iSCSI offload performance
Modified the event coalescing code for iSCSI offload to combat both corner cases and optimize performance as follows: 1. Added mechanism to loop back a second time to process any leftover CQEs that was generated by the hardware during the time the driver is busy processing previous CQEs in the bh. This not only helps the performance but also fixes the corner case when no more CQEs are being generated in the pipeline; so those leftover CQEs will get a a chance to be processed. 2. Added ARM_CQE_FP to distinguish between fast path arming versus slow path arming. This change will guarantee that the CQEs will always get a chance to be re-armed during fast path completions. 3. Removed the inline event coalescing division for perf optimization. Also fixed a division-by-zero error when the event_coal_div module param was set to 0. 4. Changed the default SQ WQEs size from 256 to 128 to match chip default. 5. Changed the cmd_per_lun from 32 to 24. Signed-off-by: Eddie Wai <eddie.wai@broadcom.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <jbottomley@parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h16
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c26
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c8
3 files changed, 31 insertions, 19 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index cfd59023227b..6bdd25a93db9 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -66,11 +66,11 @@
66#define BD_SPLIT_SIZE 32768 66#define BD_SPLIT_SIZE 32768
67 67
68/* min, max & default values for SQ/RQ/CQ size, configurable via' modparam */ 68/* min, max & default values for SQ/RQ/CQ size, configurable via' modparam */
69#define BNX2I_SQ_WQES_MIN 16 69#define BNX2I_SQ_WQES_MIN 16
70#define BNX2I_570X_SQ_WQES_MAX 128 70#define BNX2I_570X_SQ_WQES_MAX 128
71#define BNX2I_5770X_SQ_WQES_MAX 512 71#define BNX2I_5770X_SQ_WQES_MAX 512
72#define BNX2I_570X_SQ_WQES_DEFAULT 128 72#define BNX2I_570X_SQ_WQES_DEFAULT 128
73#define BNX2I_5770X_SQ_WQES_DEFAULT 256 73#define BNX2I_5770X_SQ_WQES_DEFAULT 128
74 74
75#define BNX2I_570X_CQ_WQES_MAX 128 75#define BNX2I_570X_CQ_WQES_MAX 128
76#define BNX2I_5770X_CQ_WQES_MAX 512 76#define BNX2I_5770X_CQ_WQES_MAX 512
@@ -115,6 +115,7 @@
115#define BNX2X_MAX_CQS 8 115#define BNX2X_MAX_CQS 8
116 116
117#define CNIC_ARM_CQE 1 117#define CNIC_ARM_CQE 1
118#define CNIC_ARM_CQE_FP 2
118#define CNIC_DISARM_CQE 0 119#define CNIC_DISARM_CQE 0
119 120
120#define REG_RD(__hba, offset) \ 121#define REG_RD(__hba, offset) \
@@ -666,7 +667,9 @@ enum {
666 * after HBA reset is completed by bnx2i/cnic/bnx2 667 * after HBA reset is completed by bnx2i/cnic/bnx2
667 * modules 668 * modules
668 * @state: tracks offload connection state machine 669 * @state: tracks offload connection state machine
669 * @teardown_mode: indicates if conn teardown is abortive or orderly 670 * @timestamp: tracks the start time when the ep begins to connect
671 * @num_active_cmds: tracks the number of outstanding commands for this ep
672 * @ec_shift: the amount of shift as part of the event coal calc
670 * @qp: QP information 673 * @qp: QP information
671 * @ids: contains chip allocated *context id* & driver assigned 674 * @ids: contains chip allocated *context id* & driver assigned
672 * *iscsi cid* 675 * *iscsi cid*
@@ -685,6 +688,7 @@ struct bnx2i_endpoint {
685 u32 state; 688 u32 state;
686 unsigned long timestamp; 689 unsigned long timestamp;
687 int num_active_cmds; 690 int num_active_cmds;
691 u32 ec_shift;
688 692
689 struct qp_info qp; 693 struct qp_info qp;
690 struct ep_handles ids; 694 struct ep_handles ids;
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index a8a2b6b65a3c..5c54a2d9b834 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -138,7 +138,6 @@ void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action)
138 u16 next_index; 138 u16 next_index;
139 u32 num_active_cmds; 139 u32 num_active_cmds;
140 140
141
142 /* Coalesce CQ entries only on 10G devices */ 141 /* Coalesce CQ entries only on 10G devices */
143 if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) 142 if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type))
144 return; 143 return;
@@ -148,16 +147,19 @@ void bnx2i_arm_cq_event_coalescing(struct bnx2i_endpoint *ep, u8 action)
148 * interrupts and other unwanted results 147 * interrupts and other unwanted results
149 */ 148 */
150 cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt; 149 cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt;
151 if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF)
152 return;
153 150
154 if (action == CNIC_ARM_CQE) { 151 if (action != CNIC_ARM_CQE_FP)
152 if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF)
153 return;
154
155 if (action == CNIC_ARM_CQE || action == CNIC_ARM_CQE_FP) {
155 num_active_cmds = ep->num_active_cmds; 156 num_active_cmds = ep->num_active_cmds;
156 if (num_active_cmds <= event_coal_min) 157 if (num_active_cmds <= event_coal_min)
157 next_index = 1; 158 next_index = 1;
158 else 159 else
159 next_index = event_coal_min + 160 next_index = event_coal_min +
160 (num_active_cmds - event_coal_min) / event_coal_div; 161 ((num_active_cmds - event_coal_min) >>
162 ep->ec_shift);
161 if (!next_index) 163 if (!next_index)
162 next_index = 1; 164 next_index = 1;
163 cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1; 165 cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1;
@@ -1935,7 +1937,6 @@ cqe_out:
1935 qp->cq_cons_idx++; 1937 qp->cq_cons_idx++;
1936 } 1938 }
1937 } 1939 }
1938 bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE);
1939} 1940}
1940 1941
1941/** 1942/**
@@ -1949,22 +1950,23 @@ cqe_out:
1949static void bnx2i_fastpath_notification(struct bnx2i_hba *hba, 1950static void bnx2i_fastpath_notification(struct bnx2i_hba *hba,
1950 struct iscsi_kcqe *new_cqe_kcqe) 1951 struct iscsi_kcqe *new_cqe_kcqe)
1951{ 1952{
1952 struct bnx2i_conn *conn; 1953 struct bnx2i_conn *bnx2i_conn;
1953 u32 iscsi_cid; 1954 u32 iscsi_cid;
1954 1955
1955 iscsi_cid = new_cqe_kcqe->iscsi_conn_id; 1956 iscsi_cid = new_cqe_kcqe->iscsi_conn_id;
1956 conn = bnx2i_get_conn_from_id(hba, iscsi_cid); 1957 bnx2i_conn = bnx2i_get_conn_from_id(hba, iscsi_cid);
1957 1958
1958 if (!conn) { 1959 if (!bnx2i_conn) {
1959 printk(KERN_ALERT "cid #%x not valid\n", iscsi_cid); 1960 printk(KERN_ALERT "cid #%x not valid\n", iscsi_cid);
1960 return; 1961 return;
1961 } 1962 }
1962 if (!conn->ep) { 1963 if (!bnx2i_conn->ep) {
1963 printk(KERN_ALERT "cid #%x - ep not bound\n", iscsi_cid); 1964 printk(KERN_ALERT "cid #%x - ep not bound\n", iscsi_cid);
1964 return; 1965 return;
1965 } 1966 }
1966 1967 bnx2i_process_new_cqes(bnx2i_conn);
1967 bnx2i_process_new_cqes(conn); 1968 bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE_FP);
1969 bnx2i_process_new_cqes(bnx2i_conn);
1968} 1970}
1969 1971
1970 1972
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 51a970f3bc70..041928b23cb0 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -379,6 +379,7 @@ static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba)
379{ 379{
380 struct iscsi_endpoint *ep; 380 struct iscsi_endpoint *ep;
381 struct bnx2i_endpoint *bnx2i_ep; 381 struct bnx2i_endpoint *bnx2i_ep;
382 u32 ec_div;
382 383
383 ep = iscsi_create_endpoint(sizeof(*bnx2i_ep)); 384 ep = iscsi_create_endpoint(sizeof(*bnx2i_ep));
384 if (!ep) { 385 if (!ep) {
@@ -393,6 +394,11 @@ static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba)
393 bnx2i_ep->ep_iscsi_cid = (u16) -1; 394 bnx2i_ep->ep_iscsi_cid = (u16) -1;
394 bnx2i_ep->hba = hba; 395 bnx2i_ep->hba = hba;
395 bnx2i_ep->hba_age = hba->age; 396 bnx2i_ep->hba_age = hba->age;
397
398 ec_div = event_coal_div;
399 while (ec_div >>= 1)
400 bnx2i_ep->ec_shift += 1;
401
396 hba->ofld_conns_active++; 402 hba->ofld_conns_active++;
397 init_waitqueue_head(&bnx2i_ep->ofld_wait); 403 init_waitqueue_head(&bnx2i_ep->ofld_wait);
398 return ep; 404 return ep;
@@ -2159,7 +2165,7 @@ static struct scsi_host_template bnx2i_host_template = {
2159 .change_queue_depth = iscsi_change_queue_depth, 2165 .change_queue_depth = iscsi_change_queue_depth,
2160 .can_queue = 1024, 2166 .can_queue = 1024,
2161 .max_sectors = 127, 2167 .max_sectors = 127,
2162 .cmd_per_lun = 32, 2168 .cmd_per_lun = 24,
2163 .this_id = -1, 2169 .this_id = -1,
2164 .use_clustering = ENABLE_CLUSTERING, 2170 .use_clustering = ENABLE_CLUSTERING,
2165 .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, 2171 .sg_tablesize = ISCSI_MAX_BDS_PER_CMD,