diff options
| author | Dan Williams <dan.j.williams@intel.com> | 2011-06-17 17:18:39 -0400 |
|---|---|---|
| committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:51 -0400 |
| commit | db0562509800a2d4cb5cb14a66413c30484f165c (patch) | |
| tree | d05cc34b78a8f2a6b9024b8d45e5e8e50786ee64 /drivers | |
| parent | 38d8879baeb61b6946052739e7c03fa79b3a57f0 (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')
| -rw-r--r-- | drivers/scsi/isci/host.c | 70 | ||||
| -rw-r--r-- | drivers/scsi/isci/host.h | 11 | ||||
| -rw-r--r-- | drivers/scsi/isci/remote_device.c | 9 | ||||
| -rw-r--r-- | drivers/scsi/isci/request.c | 89 | ||||
| -rw-r--r-- | drivers/scsi/isci/request.h | 26 | ||||
| -rw-r--r-- | drivers/scsi/isci/task.c | 19 |
6 files changed, 85 insertions, 139 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) | |||
| 255 | static void scic_sds_controller_task_completion(struct scic_sds_controller *scic, | 255 | static 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; | ||
