Commit a8d4b9fe authored by Tomasz Chudy's avatar Tomasz Chudy Committed by Dan Williams

isci: workaround port task scheduler starvation issue

There is a condition whereby TCs (task contexts) can jump to the head of
the round robin queue causing indefinite starvation of pending tasks.
Posting a TC to a suspended RNC (remote node context) causes the
hardware to select that task first, but since the RNC is suspended the
scheduler proceeds to the next task in the expected round robin fashion,
restoring TC arbitration fairness.
Signed-off-by: default avatarTomasz Chudy <tomasz.chudy@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 7c40a803
......@@ -147,23 +147,6 @@ enum sci_status scic_port_get_properties(
struct scic_sds_port *port,
struct scic_port_properties *properties);
/**
* scic_port_start() - This method will make the port ready for operation.
* Prior to calling the start method IO operation is not possible.
* @port: This parameter specifies the port to be started.
*
* Indicate if the port was successfully started. SCI_SUCCESS This value is
* returned if the port was successfully started. SCI_WARNING_ALREADY_IN_STATE
* This value is returned if the port is in the process of starting.
* SCI_FAILURE_INVALID_PORT This value is returned if the supplied port is not
* valid. SCI_FAILURE_INVALID_STATE This value is returned if a start operation
* can't be completed due to the state of port.
*/
enum sci_status scic_port_start(
struct scic_sds_port *port);
/**
* scic_port_stop() - This method will make the port no longer ready for
* operation. After invoking this method IO operation is not possible.
......
......@@ -796,7 +796,11 @@ enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller *scic)
enum sci_status status = SCI_SUCCESS;
for (index = 0; index < scic->logical_port_entries; index++) {
port_status = scic_port_stop(&scic->port_table[index]);
struct scic_sds_port *sci_port = &scic->port_table[index];
SCI_BASE_PORT_HANDLER_T stop;
stop = sci_port->state_handlers->parent.stop_handler;
port_status = stop(&sci_port->parent);
if ((port_status != SCI_SUCCESS) &&
(port_status != SCI_FAILURE_INVALID_STATE)) {
......@@ -806,7 +810,7 @@ enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller *scic)
"%s: Controller stop operation failed to "
"stop port %d because of status %d.\n",
__func__,
scic->port_table[index].logical_port_index,
sci_port->logical_port_index,
port_status);
}
}
......@@ -3003,7 +3007,7 @@ static enum sci_status scic_sds_controller_initialized_state_start_handler(
scic_sds_controller_ram_initialization(this_controller);
}
if (SCI_SUCCESS == result) {
if (result == SCI_SUCCESS) {
/* Build the TCi free pool */
sci_pool_initialize(this_controller->tci_pool);
for (index = 0; index < this_controller->task_context_entries; index++) {
......@@ -3017,7 +3021,7 @@ static enum sci_status scic_sds_controller_initialized_state_start_handler(
);
}
if (SCI_SUCCESS == result) {
if (result == SCI_SUCCESS) {
/*
* Before anything else lets make sure we will not be interrupted
* by the hardware. */
......@@ -3036,7 +3040,15 @@ static enum sci_status scic_sds_controller_initialized_state_start_handler(
scic_sds_controller_initialize_unsolicited_frame_queue(this_controller);
}
if (SCI_SUCCESS == result) {
/* Start all of the ports on this controller */
for (index = 0; index < this_controller->logical_port_entries &&
result == SCI_SUCCESS; index++) {
struct scic_sds_port *sci_port = &this_controller->port_table[index];
result = sci_port->state_handlers->parent.start_handler(&sci_port->parent);
}
if (result == SCI_SUCCESS) {
scic_sds_controller_start_next_phy(this_controller);
isci_event_timer_start(this_controller,
......
This diff is collapsed.
......@@ -72,6 +72,12 @@
#define SCIC_SDS_DUMMY_PORT 0xFF
/**
* This constant defines the value utilized by SCI Components to indicate
* an invalid handle.
*/
#define SCI_INVALID_HANDLE 0x0
/**
* enum SCIC_SDS_PORT_READY_SUBSTATES -
*
......@@ -134,6 +140,9 @@ struct scic_sds_port {
*/
u8 active_phy_mask;
u16 reserved_rni;
u16 reserved_tci;
/**
* This field contains the count of the io requests started on this port
* object. It is used to control controller shutdown.
......
......@@ -381,7 +381,6 @@ int isci_host_init(struct isci_host *isci_host)
int index = 0;
enum sci_status status;
struct scic_sds_controller *controller;
struct scic_sds_port *scic_port;
union scic_oem_parameters scic_oem_params;
union scic_user_parameters scic_user_params;
......@@ -517,11 +516,5 @@ int isci_host_init(struct isci_host *isci_host)
for (index = 0; index < SCI_MAX_PHYS; index++)
isci_phy_init(&isci_host->phys[index], isci_host, index);
/* Start the ports */
for (index = 0; index < SCI_MAX_PORTS; index++) {
scic_controller_get_port_handle(controller, index, &scic_port);
scic_port_start(scic_port);
}
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment