aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/host.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-06-17 17:18:39 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:04:51 -0400
commitdb0562509800a2d4cb5cb14a66413c30484f165c (patch)
treed05cc34b78a8f2a6b9024b8d45e5e8e50786ee64 /drivers/scsi/isci/host.c
parent38d8879baeb61b6946052739e7c03fa79b3a57f0 (diff)
isci: preallocate requests
the dma_pool interface is optimized for object_size << page_size which is not the case with isci_request objects and the dma_pool routines show up in the top of the profile. The old io_request_table which tracked whether tci slots were in-flight or not is replaced with an IREQ_ACTIVE flag per request. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/host.c')
-rw-r--r--drivers/scsi/isci/host.c70
1 files changed, 39 insertions, 31 deletions
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index c99fab53dd0c..0884ae3253e5 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -255,14 +255,14 @@ static bool scic_sds_controller_error_isr(struct scic_sds_controller *scic)
255static void scic_sds_controller_task_completion(struct scic_sds_controller *scic, 255static void scic_sds_controller_task_completion(struct scic_sds_controller *scic,
256 u32 completion_entry) 256 u32 completion_entry)
257{ 257{
258 u32 index; 258 u32 index = SCU_GET_COMPLETION_INDEX(completion_entry);
259 struct scic_sds_request *sci_req; 259 struct isci_host *ihost = scic_to_ihost(scic);
260 260 struct isci_request *ireq = ihost->reqs[index];
261 index = SCU_GET_COMPLETION_INDEX(completion_entry); 261 struct scic_sds_request *sci_req = &ireq->sci;
262 sci_req = scic->io_request_table[index];
263 262
264 /* Make sure that we really want to process this IO request */ 263 /* Make sure that we really want to process this IO request */
265 if (sci_req && sci_req->io_tag != SCI_CONTROLLER_INVALID_IO_TAG && 264 if (test_bit(IREQ_ACTIVE, &ireq->flags) &&
265 sci_req->io_tag != SCI_CONTROLLER_INVALID_IO_TAG &&
266 ISCI_TAG_SEQ(sci_req->io_tag) == scic->io_request_sequence[index]) 266 ISCI_TAG_SEQ(sci_req->io_tag) == scic->io_request_sequence[index])
267 /* Yep this is a valid io request pass it along to the io request handler */ 267 /* Yep this is a valid io request pass it along to the io request handler */
268 scic_sds_io_request_tc_completion(sci_req, completion_entry); 268 scic_sds_io_request_tc_completion(sci_req, completion_entry);
@@ -280,7 +280,7 @@ static void scic_sds_controller_sdma_completion(struct scic_sds_controller *scic
280 switch (scu_get_command_request_type(completion_entry)) { 280 switch (scu_get_command_request_type(completion_entry)) {
281 case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC: 281 case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC:
282 case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC: 282 case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC:
283 io_request = scic->io_request_table[index]; 283 io_request = &scic_to_ihost(scic)->reqs[index]->sci;
284 dev_warn(scic_to_dev(scic), 284 dev_warn(scic_to_dev(scic),
285 "%s: SCIC SDS Completion type SDMA %x for io request " 285 "%s: SCIC SDS Completion type SDMA %x for io request "
286 "%p\n", 286 "%p\n",
@@ -418,7 +418,7 @@ static void scic_sds_controller_event_completion(struct scic_sds_controller *sci
418 break; 418 break;
419 419
420 case SCU_EVENT_TYPE_TRANSPORT_ERROR: 420 case SCU_EVENT_TYPE_TRANSPORT_ERROR:
421 io_request = scic->io_request_table[index]; 421 io_request = &ihost->reqs[index]->sci;
422 scic_sds_io_request_event_handler(io_request, completion_entry); 422 scic_sds_io_request_event_handler(io_request, completion_entry);
423 break; 423 break;
424 424
@@ -426,7 +426,7 @@ static void scic_sds_controller_event_completion(struct scic_sds_controller *sci
426 switch (scu_get_event_specifier(completion_entry)) { 426 switch (scu_get_event_specifier(completion_entry)) {
427 case SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE: 427 case SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE:
428 case SCU_EVENT_SPECIFIC_TASK_TIMEOUT: 428 case SCU_EVENT_SPECIFIC_TASK_TIMEOUT:
429 io_request = scic->io_request_table[index]; 429 io_request = &ihost->reqs[index]->sci;
430 if (io_request != NULL) 430 if (io_request != NULL)
431 scic_sds_io_request_event_handler(io_request, completion_entry); 431 scic_sds_io_request_event_handler(io_request, completion_entry);
432 else 432 else
@@ -1187,9 +1187,6 @@ static void isci_host_completion_routine(unsigned long data)
1187 spin_lock_irq(&isci_host->scic_lock); 1187 spin_lock_irq(&isci_host->scic_lock);
1188 isci_free_tag(isci_host, request->sci.io_tag); 1188 isci_free_tag(isci_host, request->sci.io_tag);
1189 spin_unlock_irq(&isci_host->scic_lock); 1189 spin_unlock_irq(&isci_host->scic_lock);
1190
1191 /* Free the request object. */
1192 isci_request_free(isci_host, request);
1193 } 1190 }
1194 list_for_each_entry_safe(request, next_request, &errored_request_list, 1191 list_for_each_entry_safe(request, next_request, &errored_request_list,
1195 completed_node) { 1192 completed_node) {
@@ -1227,9 +1224,6 @@ static void isci_host_completion_routine(unsigned long data)
1227 list_del_init(&request->dev_node); 1224 list_del_init(&request->dev_node);
1228 isci_free_tag(isci_host, request->sci.io_tag); 1225 isci_free_tag(isci_host, request->sci.io_tag);
1229 spin_unlock_irq(&isci_host->scic_lock); 1226 spin_unlock_irq(&isci_host->scic_lock);
1230
1231 /* Free the request object. */
1232 isci_request_free(isci_host, request);
1233 } 1227 }
1234 } 1228 }
1235 1229
@@ -2469,13 +2463,6 @@ int isci_host_init(struct isci_host *isci_host)
2469 if (err) 2463 if (err)
2470 return err; 2464 return err;
2471 2465
2472 isci_host->dma_pool = dmam_pool_create(DRV_NAME, &isci_host->pdev->dev,
2473 sizeof(struct isci_request),
2474 SLAB_HWCACHE_ALIGN, 0);
2475
2476 if (!isci_host->dma_pool)
2477 return -ENOMEM;
2478
2479 for (i = 0; i < SCI_MAX_PORTS; i++) 2466 for (i = 0; i < SCI_MAX_PORTS; i++)
2480 isci_port_init(&isci_host->ports[i], isci_host, i); 2467 isci_port_init(&isci_host->ports[i], isci_host, i);
2481 2468
@@ -2489,6 +2476,25 @@ int isci_host_init(struct isci_host *isci_host)
2489 INIT_LIST_HEAD(&idev->node); 2476 INIT_LIST_HEAD(&idev->node);
2490 } 2477 }
2491 2478
2479 for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) {
2480 struct isci_request *ireq;
2481 dma_addr_t dma;
2482
2483 ireq = dmam_alloc_coherent(&isci_host->pdev->dev,
2484 sizeof(struct isci_request), &dma,
2485 GFP_KERNEL);
2486 if (!ireq)
2487 return -ENOMEM;
2488
2489 ireq->sci.tc = &isci_host->sci.task_context_table[i];
2490 ireq->sci.owning_controller = &isci_host->sci;
2491 spin_lock_init(&ireq->state_lock);
2492 ireq->request_daddr = dma;
2493 ireq->isci_host = isci_host;
2494
2495 isci_host->reqs[i] = ireq;
2496 }
2497
2492 return 0; 2498 return 0;
2493} 2499}
2494 2500
@@ -2602,12 +2608,13 @@ struct scic_sds_request *scic_request_by_tag(struct scic_sds_controller *scic, u
2602 task_index = ISCI_TAG_TCI(io_tag); 2608 task_index = ISCI_TAG_TCI(io_tag);
2603 2609
2604 if (task_index < scic->task_context_entries) { 2610 if (task_index < scic->task_context_entries) {
2605 if (scic->io_request_table[task_index] != NULL) { 2611 struct isci_request *ireq = scic_to_ihost(scic)->reqs[task_index];
2612
2613 if (test_bit(IREQ_ACTIVE, &ireq->flags)) {
2606 task_sequence = ISCI_TAG_SEQ(io_tag); 2614 task_sequence = ISCI_TAG_SEQ(io_tag);
2607 2615
2608 if (task_sequence == scic->io_request_sequence[task_index]) { 2616 if (task_sequence == scic->io_request_sequence[task_index])
2609 return scic->io_request_table[task_index]; 2617 return &ireq->sci;
2610 }
2611 } 2618 }
2612 } 2619 }
2613 2620
@@ -2820,7 +2827,7 @@ enum sci_status scic_controller_start_io(struct scic_sds_controller *scic,
2820 if (status != SCI_SUCCESS) 2827 if (status != SCI_SUCCESS)
2821 return status; 2828 return status;
2822 2829
2823 scic->io_request_table[ISCI_TAG_TCI(req->io_tag)] = req; 2830 set_bit(IREQ_ACTIVE, &sci_req_to_ireq(req)->flags);
2824 scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(req)); 2831 scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(req));
2825 return SCI_SUCCESS; 2832 return SCI_SUCCESS;
2826} 2833}
@@ -2897,7 +2904,7 @@ enum sci_status scic_controller_complete_io(
2897 return status; 2904 return status;
2898 2905
2899 index = ISCI_TAG_TCI(request->io_tag); 2906 index = ISCI_TAG_TCI(request->io_tag);
2900 scic->io_request_table[index] = NULL; 2907 clear_bit(IREQ_ACTIVE, &sci_req_to_ireq(request)->flags);
2901 return SCI_SUCCESS; 2908 return SCI_SUCCESS;
2902 default: 2909 default:
2903 dev_warn(scic_to_dev(scic), "invalid state to complete I/O"); 2910 dev_warn(scic_to_dev(scic), "invalid state to complete I/O");
@@ -2915,7 +2922,7 @@ enum sci_status scic_controller_continue_io(struct scic_sds_request *sci_req)
2915 return SCI_FAILURE_INVALID_STATE; 2922 return SCI_FAILURE_INVALID_STATE;
2916 } 2923 }
2917 2924
2918 scic->io_request_table[ISCI_TAG_TCI(sci_req->io_tag)] = sci_req; 2925 set_bit(IREQ_ACTIVE, &sci_req_to_ireq(sci_req)->flags);
2919 scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(sci_req)); 2926 scic_sds_controller_post_request(scic, scic_sds_request_get_post_context(sci_req));
2920 return SCI_SUCCESS; 2927 return SCI_SUCCESS;
2921} 2928}
@@ -2934,6 +2941,7 @@ enum sci_task_status scic_controller_start_task(
2934 struct scic_sds_remote_device *rdev, 2941 struct scic_sds_remote_device *rdev,
2935 struct scic_sds_request *req) 2942 struct scic_sds_request *req)
2936{ 2943{
2944 struct isci_request *ireq = sci_req_to_ireq(req);
2937 enum sci_status status; 2945 enum sci_status status;
2938 2946
2939 if (scic->sm.current_state_id != SCIC_READY) { 2947 if (scic->sm.current_state_id != SCIC_READY) {
@@ -2947,7 +2955,7 @@ enum sci_task_status scic_controller_start_task(
2947 status = scic_sds_remote_device_start_task(scic, rdev, req); 2955 status = scic_sds_remote_device_start_task(scic, rdev, req);
2948 switch (status) { 2956 switch (status) {
2949 case SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS: 2957 case SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS:
2950 scic->io_request_table[ISCI_TAG_TCI(req->io_tag)] = req; 2958 set_bit(IREQ_ACTIVE, &ireq->flags);
2951 2959
2952 /* 2960 /*
2953 * We will let framework know this task request started successfully, 2961 * We will let framework know this task request started successfully,
@@ -2956,7 +2964,7 @@ enum sci_task_status scic_controller_start_task(
2956 */ 2964 */
2957 return SCI_SUCCESS; 2965 return SCI_SUCCESS;
2958 case SCI_SUCCESS: 2966 case SCI_SUCCESS:
2959 scic->io_request_table[ISCI_TAG_TCI(req->io_tag)] = req; 2967 set_bit(IREQ_ACTIVE, &ireq->flags);
2960 2968
2961 scic_sds_controller_post_request(scic, 2969 scic_sds_controller_post_request(scic,
2962 scic_sds_request_get_post_context(req)); 2970 scic_sds_request_get_post_context(req));