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/scsi/isci/host.c | |
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/scsi/isci/host.c')
-rw-r--r-- | drivers/scsi/isci/host.c | 70 |
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) | |||
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; | 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)); |