Skip to content

Commit

Permalink
isci: workaround port task scheduler starvation issue
Browse files Browse the repository at this point in the history
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: Tomasz Chudy <tomasz.chudy@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Tomasz Chudy authored and djbw committed Jul 3, 2011
1 parent 7c40a80 commit a8d4b9f
Show file tree
Hide file tree
Showing 5 changed files with 298 additions and 91 deletions.
17 changes: 0 additions & 17 deletions drivers/scsi/isci/core/scic_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
22 changes: 17 additions & 5 deletions drivers/scsi/isci/core/scic_sds_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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++) {
Expand All @@ -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. */
Expand All @@ -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,
Expand Down
Loading

0 comments on commit a8d4b9f

Please sign in to comment.