Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1892fc2e authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman
Browse files

mei: stop the stall timer worker if not needed



The stall timer worker checks periodically if there is a stalled i/o
transaction. The issue with the current implementation is that the timer
is ticking also when there is no pending i/o transaction.
This patch provides a simple change that prevents rescheduling
of the delayed work when there is no pending i/o.

Cc: Andy Lutomirski <luto@kernel.org>
Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6eb1c949
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -277,6 +277,7 @@ void mei_amthif_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
	case MEI_FOP_WRITE:
		if (!cb->status) {
			dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER;
			mei_schedule_stall_timer(dev);
			mei_io_cb_free(cb);
			return;
		}
+2 −0
Original line number Diff line number Diff line
@@ -826,6 +826,7 @@ static int mei_cl_send_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb)

	list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
	cl->timer_count = MEI_CONNECT_TIMEOUT;
	mei_schedule_stall_timer(dev);

	return 0;
}
@@ -1011,6 +1012,7 @@ static int mei_cl_send_connect(struct mei_cl *cl, struct mei_cl_cb *cb)

	list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
	cl->timer_count = MEI_CONNECT_TIMEOUT;
	mei_schedule_stall_timer(dev);
	return 0;
}

+3 −0
Original line number Diff line number Diff line
@@ -277,6 +277,7 @@ int mei_hbm_start_req(struct mei_device *dev)

	dev->hbm_state = MEI_HBM_STARTING;
	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
	mei_schedule_stall_timer(dev);
	return 0;
}

@@ -312,6 +313,7 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev)
	}
	dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
	mei_schedule_stall_timer(dev);
	return 0;
}

@@ -562,6 +564,7 @@ static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx)
	}

	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
	mei_schedule_stall_timer(dev);

	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ void mei_cancel_work(struct mei_device *dev)
	cancel_work_sync(&dev->reset_work);
	cancel_work_sync(&dev->bus_rescan_work);

	cancel_delayed_work(&dev->timer_work);
	cancel_delayed_work_sync(&dev->timer_work);
}
EXPORT_SYMBOL_GPL(mei_cancel_work);

+21 −4
Original line number Diff line number Diff line
@@ -459,6 +459,19 @@ static void mei_connect_timeout(struct mei_cl *cl)
	mei_reset(dev);
}

#define MEI_STALL_TIMER_FREQ (2 * HZ)
/**
 * mei_schedule_stall_timer - re-arm stall_timer work
 *
 * Schedule stall timer
 *
 * @dev: the device structure
 */
void mei_schedule_stall_timer(struct mei_device *dev)
{
	schedule_delayed_work(&dev->timer_work, MEI_STALL_TIMER_FREQ);
}

/**
 * mei_timer - timer function.
 *
@@ -468,10 +481,9 @@ static void mei_connect_timeout(struct mei_cl *cl)
void mei_timer(struct work_struct *work)
{
	struct mei_cl *cl;

	struct mei_device *dev = container_of(work,
					struct mei_device, timer_work.work);

	bool reschedule_timer = false;

	mutex_lock(&dev->device_lock);

@@ -486,6 +498,7 @@ void mei_timer(struct work_struct *work)
				mei_reset(dev);
				goto out;
			}
			reschedule_timer = true;
		}
	}

@@ -500,6 +513,7 @@ void mei_timer(struct work_struct *work)
				mei_connect_timeout(cl);
				goto out;
			}
			reschedule_timer = true;
		}
	}

@@ -512,11 +526,14 @@ void mei_timer(struct work_struct *work)
			mei_reset(dev);

			mei_amthif_run_next_cmd(dev);
			goto out;
		}
		reschedule_timer = true;
	}

out:
	if (dev->dev_state != MEI_DEV_DISABLED)
		schedule_delayed_work(&dev->timer_work, 2 * HZ);
	if (dev->dev_state != MEI_DEV_DISABLED && reschedule_timer)
		mei_schedule_stall_timer(dev);

	mutex_unlock(&dev->device_lock);
}
Loading