diff options
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc.h | 15 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 2 | ||||
-rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_io.c | 73 |
3 files changed, 58 insertions, 32 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index df2fc09ba479..464d71ea31aa 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h | |||
@@ -84,7 +84,9 @@ | |||
84 | #define BNX2FC_NUM_MAX_SESS 128 | 84 | #define BNX2FC_NUM_MAX_SESS 128 |
85 | #define BNX2FC_NUM_MAX_SESS_LOG (ilog2(BNX2FC_NUM_MAX_SESS)) | 85 | #define BNX2FC_NUM_MAX_SESS_LOG (ilog2(BNX2FC_NUM_MAX_SESS)) |
86 | 86 | ||
87 | #define BNX2FC_MAX_OUTSTANDING_CMNDS 4096 | 87 | #define BNX2FC_MAX_OUTSTANDING_CMNDS 2048 |
88 | #define BNX2FC_CAN_QUEUE BNX2FC_MAX_OUTSTANDING_CMNDS | ||
89 | #define BNX2FC_ELSTM_XIDS BNX2FC_CAN_QUEUE | ||
88 | #define BNX2FC_MIN_PAYLOAD 256 | 90 | #define BNX2FC_MIN_PAYLOAD 256 |
89 | #define BNX2FC_MAX_PAYLOAD 2048 | 91 | #define BNX2FC_MAX_PAYLOAD 2048 |
90 | 92 | ||
@@ -98,7 +100,8 @@ | |||
98 | #define BNX2FC_CONFQ_WQE_SIZE (sizeof(struct fcoe_confqe)) | 100 | #define BNX2FC_CONFQ_WQE_SIZE (sizeof(struct fcoe_confqe)) |
99 | #define BNX2FC_5771X_DB_PAGE_SIZE 128 | 101 | #define BNX2FC_5771X_DB_PAGE_SIZE 128 |
100 | 102 | ||
101 | #define BNX2FC_MAX_TASKS BNX2FC_MAX_OUTSTANDING_CMNDS | 103 | #define BNX2FC_MAX_TASKS \ |
104 | (BNX2FC_MAX_OUTSTANDING_CMNDS + BNX2FC_ELSTM_XIDS) | ||
102 | #define BNX2FC_TASK_SIZE 128 | 105 | #define BNX2FC_TASK_SIZE 128 |
103 | #define BNX2FC_TASKS_PER_PAGE (PAGE_SIZE/BNX2FC_TASK_SIZE) | 106 | #define BNX2FC_TASKS_PER_PAGE (PAGE_SIZE/BNX2FC_TASK_SIZE) |
104 | #define BNX2FC_TASK_CTX_ARR_SZ (BNX2FC_MAX_TASKS/BNX2FC_TASKS_PER_PAGE) | 107 | #define BNX2FC_TASK_CTX_ARR_SZ (BNX2FC_MAX_TASKS/BNX2FC_TASKS_PER_PAGE) |
@@ -112,10 +115,10 @@ | |||
112 | #define BNX2FC_WRITE (1 << 0) | 115 | #define BNX2FC_WRITE (1 << 0) |
113 | 116 | ||
114 | #define BNX2FC_MIN_XID 0 | 117 | #define BNX2FC_MIN_XID 0 |
115 | #define BNX2FC_MAX_XID (BNX2FC_MAX_OUTSTANDING_CMNDS - 1) | 118 | #define BNX2FC_MAX_XID \ |
116 | #define FCOE_MIN_XID (BNX2FC_MAX_OUTSTANDING_CMNDS) | 119 | (BNX2FC_MAX_OUTSTANDING_CMNDS + BNX2FC_ELSTM_XIDS - 1) |
117 | #define FCOE_MAX_XID \ | 120 | #define FCOE_MIN_XID (BNX2FC_MAX_XID + 1) |
118 | (BNX2FC_MAX_OUTSTANDING_CMNDS + (nr_cpu_ids * 256)) | 121 | #define FCOE_MAX_XID (FCOE_MIN_XID + 4095) |
119 | #define BNX2FC_MAX_LUN 0xFFFF | 122 | #define BNX2FC_MAX_LUN 0xFFFF |
120 | #define BNX2FC_MAX_FCP_TGT 256 | 123 | #define BNX2FC_MAX_FCP_TGT 256 |
121 | #define BNX2FC_MAX_CMD_LEN 16 | 124 | #define BNX2FC_MAX_CMD_LEN 16 |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 13271a43cd35..90cd632eed91 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | |||
@@ -2497,7 +2497,7 @@ static struct scsi_host_template bnx2fc_shost_template = { | |||
2497 | .change_queue_type = fc_change_queue_type, | 2497 | .change_queue_type = fc_change_queue_type, |
2498 | .this_id = -1, | 2498 | .this_id = -1, |
2499 | .cmd_per_lun = 3, | 2499 | .cmd_per_lun = 3, |
2500 | .can_queue = (BNX2FC_MAX_OUTSTANDING_CMNDS/2), | 2500 | .can_queue = BNX2FC_CAN_QUEUE, |
2501 | .use_clustering = ENABLE_CLUSTERING, | 2501 | .use_clustering = ENABLE_CLUSTERING, |
2502 | .sg_tablesize = BNX2FC_MAX_BDS_PER_CMD, | 2502 | .sg_tablesize = BNX2FC_MAX_BDS_PER_CMD, |
2503 | .max_sectors = 512, | 2503 | .max_sectors = 512, |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 0f1dd23730db..d3fc302c241a 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c | |||
@@ -11,6 +11,9 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "bnx2fc.h" | 13 | #include "bnx2fc.h" |
14 | |||
15 | #define RESERVE_FREE_LIST_INDEX num_possible_cpus() | ||
16 | |||
14 | static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len, | 17 | static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len, |
15 | int bd_index); | 18 | int bd_index); |
16 | static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req); | 19 | static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req); |
@@ -242,8 +245,9 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba, | |||
242 | u32 mem_size; | 245 | u32 mem_size; |
243 | u16 xid; | 246 | u16 xid; |
244 | int i; | 247 | int i; |
245 | int num_ios; | 248 | int num_ios, num_pri_ios; |
246 | size_t bd_tbl_sz; | 249 | size_t bd_tbl_sz; |
250 | int arr_sz = num_possible_cpus() + 1; | ||
247 | 251 | ||
248 | if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN) { | 252 | if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN) { |
249 | printk(KERN_ERR PFX "cmd_mgr_alloc: Invalid min_xid 0x%x \ | 253 | printk(KERN_ERR PFX "cmd_mgr_alloc: Invalid min_xid 0x%x \ |
@@ -263,14 +267,14 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba, | |||
263 | } | 267 | } |
264 | 268 | ||
265 | cmgr->free_list = kzalloc(sizeof(*cmgr->free_list) * | 269 | cmgr->free_list = kzalloc(sizeof(*cmgr->free_list) * |
266 | num_possible_cpus(), GFP_KERNEL); | 270 | arr_sz, GFP_KERNEL); |
267 | if (!cmgr->free_list) { | 271 | if (!cmgr->free_list) { |
268 | printk(KERN_ERR PFX "failed to alloc free_list\n"); | 272 | printk(KERN_ERR PFX "failed to alloc free_list\n"); |
269 | goto mem_err; | 273 | goto mem_err; |
270 | } | 274 | } |
271 | 275 | ||
272 | cmgr->free_list_lock = kzalloc(sizeof(*cmgr->free_list_lock) * | 276 | cmgr->free_list_lock = kzalloc(sizeof(*cmgr->free_list_lock) * |
273 | num_possible_cpus(), GFP_KERNEL); | 277 | arr_sz, GFP_KERNEL); |
274 | if (!cmgr->free_list_lock) { | 278 | if (!cmgr->free_list_lock) { |
275 | printk(KERN_ERR PFX "failed to alloc free_list_lock\n"); | 279 | printk(KERN_ERR PFX "failed to alloc free_list_lock\n"); |
276 | goto mem_err; | 280 | goto mem_err; |
@@ -279,13 +283,18 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba, | |||
279 | cmgr->hba = hba; | 283 | cmgr->hba = hba; |
280 | cmgr->cmds = (struct bnx2fc_cmd **)(cmgr + 1); | 284 | cmgr->cmds = (struct bnx2fc_cmd **)(cmgr + 1); |
281 | 285 | ||
282 | for (i = 0; i < num_possible_cpus(); i++) { | 286 | for (i = 0; i < arr_sz; i++) { |
283 | INIT_LIST_HEAD(&cmgr->free_list[i]); | 287 | INIT_LIST_HEAD(&cmgr->free_list[i]); |
284 | spin_lock_init(&cmgr->free_list_lock[i]); | 288 | spin_lock_init(&cmgr->free_list_lock[i]); |
285 | } | 289 | } |
286 | 290 | ||
287 | /* Pre-allocated pool of bnx2fc_cmds */ | 291 | /* |
292 | * Pre-allocated pool of bnx2fc_cmds. | ||
293 | * Last entry in the free list array is the free list | ||
294 | * of slow path requests. | ||
295 | */ | ||
288 | xid = BNX2FC_MIN_XID; | 296 | xid = BNX2FC_MIN_XID; |
297 | num_pri_ios = num_ios - BNX2FC_ELSTM_XIDS; | ||
289 | for (i = 0; i < num_ios; i++) { | 298 | for (i = 0; i < num_ios; i++) { |
290 | io_req = kzalloc(sizeof(*io_req), GFP_KERNEL); | 299 | io_req = kzalloc(sizeof(*io_req), GFP_KERNEL); |
291 | 300 | ||
@@ -298,11 +307,13 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba, | |||
298 | INIT_DELAYED_WORK(&io_req->timeout_work, bnx2fc_cmd_timeout); | 307 | INIT_DELAYED_WORK(&io_req->timeout_work, bnx2fc_cmd_timeout); |
299 | 308 | ||
300 | io_req->xid = xid++; | 309 | io_req->xid = xid++; |
301 | if (io_req->xid >= BNX2FC_MAX_OUTSTANDING_CMNDS) | 310 | if (i < num_pri_ios) |
302 | printk(KERN_ERR PFX "ERROR allocating xids - 0x%x\n", | 311 | list_add_tail(&io_req->link, |
303 | io_req->xid); | 312 | &cmgr->free_list[io_req->xid % |
304 | list_add_tail(&io_req->link, | 313 | num_possible_cpus()]); |
305 | &cmgr->free_list[io_req->xid % num_possible_cpus()]); | 314 | else |
315 | list_add_tail(&io_req->link, | ||
316 | &cmgr->free_list[num_possible_cpus()]); | ||
306 | io_req++; | 317 | io_req++; |
307 | } | 318 | } |
308 | 319 | ||
@@ -389,7 +400,7 @@ free_cmd_pool: | |||
389 | if (!cmgr->free_list) | 400 | if (!cmgr->free_list) |
390 | goto free_cmgr; | 401 | goto free_cmgr; |
391 | 402 | ||
392 | for (i = 0; i < num_possible_cpus(); i++) { | 403 | for (i = 0; i < num_possible_cpus() + 1; i++) { |
393 | struct list_head *list; | 404 | struct list_head *list; |
394 | struct list_head *tmp; | 405 | struct list_head *tmp; |
395 | 406 | ||
@@ -413,6 +424,7 @@ struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type) | |||
413 | struct bnx2fc_cmd *io_req; | 424 | struct bnx2fc_cmd *io_req; |
414 | struct list_head *listp; | 425 | struct list_head *listp; |
415 | struct io_bdt *bd_tbl; | 426 | struct io_bdt *bd_tbl; |
427 | int index = RESERVE_FREE_LIST_INDEX; | ||
416 | u32 max_sqes; | 428 | u32 max_sqes; |
417 | u16 xid; | 429 | u16 xid; |
418 | 430 | ||
@@ -432,26 +444,26 @@ struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type) | |||
432 | * NOTE: Free list insertions and deletions are protected with | 444 | * NOTE: Free list insertions and deletions are protected with |
433 | * cmgr lock | 445 | * cmgr lock |
434 | */ | 446 | */ |
435 | spin_lock_bh(&cmd_mgr->free_list_lock[smp_processor_id()]); | 447 | spin_lock_bh(&cmd_mgr->free_list_lock[index]); |
436 | if ((list_empty(&(cmd_mgr->free_list[smp_processor_id()]))) || | 448 | if ((list_empty(&(cmd_mgr->free_list[index]))) || |
437 | (tgt->num_active_ios.counter >= max_sqes)) { | 449 | (tgt->num_active_ios.counter >= max_sqes)) { |
438 | BNX2FC_TGT_DBG(tgt, "No free els_tm cmds available " | 450 | BNX2FC_TGT_DBG(tgt, "No free els_tm cmds available " |
439 | "ios(%d):sqes(%d)\n", | 451 | "ios(%d):sqes(%d)\n", |
440 | tgt->num_active_ios.counter, tgt->max_sqes); | 452 | tgt->num_active_ios.counter, tgt->max_sqes); |
441 | if (list_empty(&(cmd_mgr->free_list[smp_processor_id()]))) | 453 | if (list_empty(&(cmd_mgr->free_list[index]))) |
442 | printk(KERN_ERR PFX "elstm_alloc: list_empty\n"); | 454 | printk(KERN_ERR PFX "elstm_alloc: list_empty\n"); |
443 | spin_unlock_bh(&cmd_mgr->free_list_lock[smp_processor_id()]); | 455 | spin_unlock_bh(&cmd_mgr->free_list_lock[index]); |
444 | return NULL; | 456 | return NULL; |
445 | } | 457 | } |
446 | 458 | ||
447 | listp = (struct list_head *) | 459 | listp = (struct list_head *) |
448 | cmd_mgr->free_list[smp_processor_id()].next; | 460 | cmd_mgr->free_list[index].next; |
449 | list_del_init(listp); | 461 | list_del_init(listp); |
450 | io_req = (struct bnx2fc_cmd *) listp; | 462 | io_req = (struct bnx2fc_cmd *) listp; |
451 | xid = io_req->xid; | 463 | xid = io_req->xid; |
452 | cmd_mgr->cmds[xid] = io_req; | 464 | cmd_mgr->cmds[xid] = io_req; |
453 | atomic_inc(&tgt->num_active_ios); | 465 | atomic_inc(&tgt->num_active_ios); |
454 | spin_unlock_bh(&cmd_mgr->free_list_lock[smp_processor_id()]); | 466 | spin_unlock_bh(&cmd_mgr->free_list_lock[index]); |
455 | 467 | ||
456 | INIT_LIST_HEAD(&io_req->link); | 468 | INIT_LIST_HEAD(&io_req->link); |
457 | 469 | ||
@@ -479,27 +491,30 @@ static struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt) | |||
479 | struct io_bdt *bd_tbl; | 491 | struct io_bdt *bd_tbl; |
480 | u32 max_sqes; | 492 | u32 max_sqes; |
481 | u16 xid; | 493 | u16 xid; |
494 | int index = get_cpu(); | ||
482 | 495 | ||
483 | max_sqes = BNX2FC_SCSI_MAX_SQES; | 496 | max_sqes = BNX2FC_SCSI_MAX_SQES; |
484 | /* | 497 | /* |
485 | * NOTE: Free list insertions and deletions are protected with | 498 | * NOTE: Free list insertions and deletions are protected with |
486 | * cmgr lock | 499 | * cmgr lock |
487 | */ | 500 | */ |
488 | spin_lock_bh(&cmd_mgr->free_list_lock[smp_processor_id()]); | 501 | spin_lock_bh(&cmd_mgr->free_list_lock[index]); |
489 | if ((list_empty(&cmd_mgr->free_list[smp_processor_id()])) || | 502 | if ((list_empty(&cmd_mgr->free_list[index])) || |
490 | (tgt->num_active_ios.counter >= max_sqes)) { | 503 | (tgt->num_active_ios.counter >= max_sqes)) { |
491 | spin_unlock_bh(&cmd_mgr->free_list_lock[smp_processor_id()]); | 504 | spin_unlock_bh(&cmd_mgr->free_list_lock[index]); |
505 | put_cpu(); | ||
492 | return NULL; | 506 | return NULL; |
493 | } | 507 | } |
494 | 508 | ||
495 | listp = (struct list_head *) | 509 | listp = (struct list_head *) |
496 | cmd_mgr->free_list[smp_processor_id()].next; | 510 | cmd_mgr->free_list[index].next; |
497 | list_del_init(listp); | 511 | list_del_init(listp); |
498 | io_req = (struct bnx2fc_cmd *) listp; | 512 | io_req = (struct bnx2fc_cmd *) listp; |
499 | xid = io_req->xid; | 513 | xid = io_req->xid; |
500 | cmd_mgr->cmds[xid] = io_req; | 514 | cmd_mgr->cmds[xid] = io_req; |
501 | atomic_inc(&tgt->num_active_ios); | 515 | atomic_inc(&tgt->num_active_ios); |
502 | spin_unlock_bh(&cmd_mgr->free_list_lock[smp_processor_id()]); | 516 | spin_unlock_bh(&cmd_mgr->free_list_lock[index]); |
517 | put_cpu(); | ||
503 | 518 | ||
504 | INIT_LIST_HEAD(&io_req->link); | 519 | INIT_LIST_HEAD(&io_req->link); |
505 | 520 | ||
@@ -522,8 +537,15 @@ void bnx2fc_cmd_release(struct kref *ref) | |||
522 | struct bnx2fc_cmd *io_req = container_of(ref, | 537 | struct bnx2fc_cmd *io_req = container_of(ref, |
523 | struct bnx2fc_cmd, refcount); | 538 | struct bnx2fc_cmd, refcount); |
524 | struct bnx2fc_cmd_mgr *cmd_mgr = io_req->cmd_mgr; | 539 | struct bnx2fc_cmd_mgr *cmd_mgr = io_req->cmd_mgr; |
540 | int index; | ||
541 | |||
542 | if (io_req->cmd_type == BNX2FC_SCSI_CMD) | ||
543 | index = io_req->xid % num_possible_cpus(); | ||
544 | else | ||
545 | index = RESERVE_FREE_LIST_INDEX; | ||
525 | 546 | ||
526 | spin_lock_bh(&cmd_mgr->free_list_lock[smp_processor_id()]); | 547 | |
548 | spin_lock_bh(&cmd_mgr->free_list_lock[index]); | ||
527 | if (io_req->cmd_type != BNX2FC_SCSI_CMD) | 549 | if (io_req->cmd_type != BNX2FC_SCSI_CMD) |
528 | bnx2fc_free_mp_resc(io_req); | 550 | bnx2fc_free_mp_resc(io_req); |
529 | cmd_mgr->cmds[io_req->xid] = NULL; | 551 | cmd_mgr->cmds[io_req->xid] = NULL; |
@@ -531,9 +553,10 @@ void bnx2fc_cmd_release(struct kref *ref) | |||
531 | list_del_init(&io_req->link); | 553 | list_del_init(&io_req->link); |
532 | /* Add it to the free list */ | 554 | /* Add it to the free list */ |
533 | list_add(&io_req->link, | 555 | list_add(&io_req->link, |
534 | &cmd_mgr->free_list[smp_processor_id()]); | 556 | &cmd_mgr->free_list[index]); |
535 | atomic_dec(&io_req->tgt->num_active_ios); | 557 | atomic_dec(&io_req->tgt->num_active_ios); |
536 | spin_unlock_bh(&cmd_mgr->free_list_lock[smp_processor_id()]); | 558 | spin_unlock_bh(&cmd_mgr->free_list_lock[index]); |
559 | |||
537 | } | 560 | } |
538 | 561 | ||
539 | static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req) | 562 | static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req) |