mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-27 03:47:43 +00:00
[SCSI] isci: dynamic interrupt coalescing
Hardware allows both an outstanding number commands and a timeout value (whichever occurs first) as a gate to the next interrupt generation. This scheme at completion time looks at the remaining number of outstanding tasks and sets the timeout to maximize small transaction operation. If transactions are large (take more than a few 10s of microseconds to complete) then performance is not interrupt processing bound, so the small timeouts this scheme generates are overridden by the time it takes for a completion to arrive. Tested-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
39ea2c5b5f
commit
9b4be52899
@ -1091,6 +1091,7 @@ static void isci_host_completion_routine(unsigned long data)
|
|||||||
struct isci_request *request;
|
struct isci_request *request;
|
||||||
struct isci_request *next_request;
|
struct isci_request *next_request;
|
||||||
struct sas_task *task;
|
struct sas_task *task;
|
||||||
|
u16 active;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&completed_request_list);
|
INIT_LIST_HEAD(&completed_request_list);
|
||||||
INIT_LIST_HEAD(&errored_request_list);
|
INIT_LIST_HEAD(&errored_request_list);
|
||||||
@ -1181,6 +1182,13 @@ static void isci_host_completion_routine(unsigned long data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* the coalesence timeout doubles at each encoding step, so
|
||||||
|
* update it based on the ilog2 value of the outstanding requests
|
||||||
|
*/
|
||||||
|
active = isci_tci_active(ihost);
|
||||||
|
writel(SMU_ICC_GEN_VAL(NUMBER, active) |
|
||||||
|
SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)),
|
||||||
|
&ihost->smu_registers->interrupt_coalesce_control);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1471,7 +1479,7 @@ static void sci_controller_ready_state_enter(struct sci_base_state_machine *sm)
|
|||||||
struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
|
struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
|
||||||
|
|
||||||
/* set the default interrupt coalescence number and timeout value. */
|
/* set the default interrupt coalescence number and timeout value. */
|
||||||
sci_controller_set_interrupt_coalescence(ihost, 0x10, 250);
|
sci_controller_set_interrupt_coalescence(ihost, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm)
|
static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm)
|
||||||
|
@ -369,6 +369,9 @@ static inline struct isci_host *dev_to_ihost(struct domain_device *dev)
|
|||||||
#define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1))
|
#define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1))
|
||||||
#define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1))
|
#define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1))
|
||||||
|
|
||||||
|
/* interrupt coalescing baseline: 9 == 3 to 5us interrupt delay per command */
|
||||||
|
#define ISCI_COALESCE_BASE 9
|
||||||
|
|
||||||
/* expander attached sata devices require 3 rnc slots */
|
/* expander attached sata devices require 3 rnc slots */
|
||||||
static inline int sci_remote_device_node_count(struct isci_remote_device *idev)
|
static inline int sci_remote_device_node_count(struct isci_remote_device *idev)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user