提交 1892fc2e 编写于 作者: A Alexander Usyskin 提交者: Greg Kroah-Hartman

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: NAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: NTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 6eb1c949
...@@ -277,6 +277,7 @@ void mei_amthif_complete(struct mei_cl *cl, struct mei_cl_cb *cb) ...@@ -277,6 +277,7 @@ void mei_amthif_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
case MEI_FOP_WRITE: case MEI_FOP_WRITE:
if (!cb->status) { if (!cb->status) {
dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER;
mei_schedule_stall_timer(dev);
mei_io_cb_free(cb); mei_io_cb_free(cb);
return; return;
} }
......
...@@ -826,6 +826,7 @@ static int mei_cl_send_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb) ...@@ -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); list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
cl->timer_count = MEI_CONNECT_TIMEOUT; cl->timer_count = MEI_CONNECT_TIMEOUT;
mei_schedule_stall_timer(dev);
return 0; return 0;
} }
...@@ -1011,6 +1012,7 @@ static int mei_cl_send_connect(struct mei_cl *cl, struct mei_cl_cb *cb) ...@@ -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); list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
cl->timer_count = MEI_CONNECT_TIMEOUT; cl->timer_count = MEI_CONNECT_TIMEOUT;
mei_schedule_stall_timer(dev);
return 0; return 0;
} }
......
...@@ -277,6 +277,7 @@ int mei_hbm_start_req(struct mei_device *dev) ...@@ -277,6 +277,7 @@ int mei_hbm_start_req(struct mei_device *dev)
dev->hbm_state = MEI_HBM_STARTING; dev->hbm_state = MEI_HBM_STARTING;
dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
mei_schedule_stall_timer(dev);
return 0; return 0;
} }
...@@ -312,6 +313,7 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev) ...@@ -312,6 +313,7 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev)
} }
dev->hbm_state = MEI_HBM_ENUM_CLIENTS; dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
mei_schedule_stall_timer(dev);
return 0; return 0;
} }
...@@ -562,6 +564,7 @@ static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx) ...@@ -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; dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
mei_schedule_stall_timer(dev);
return 0; return 0;
} }
......
...@@ -94,7 +94,7 @@ void mei_cancel_work(struct mei_device *dev) ...@@ -94,7 +94,7 @@ void mei_cancel_work(struct mei_device *dev)
cancel_work_sync(&dev->reset_work); cancel_work_sync(&dev->reset_work);
cancel_work_sync(&dev->bus_rescan_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); EXPORT_SYMBOL_GPL(mei_cancel_work);
......
...@@ -459,6 +459,19 @@ static void mei_connect_timeout(struct mei_cl *cl) ...@@ -459,6 +459,19 @@ static void mei_connect_timeout(struct mei_cl *cl)
mei_reset(dev); 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. * mei_timer - timer function.
* *
...@@ -468,10 +481,9 @@ static void mei_connect_timeout(struct mei_cl *cl) ...@@ -468,10 +481,9 @@ static void mei_connect_timeout(struct mei_cl *cl)
void mei_timer(struct work_struct *work) void mei_timer(struct work_struct *work)
{ {
struct mei_cl *cl; struct mei_cl *cl;
struct mei_device *dev = container_of(work, struct mei_device *dev = container_of(work,
struct mei_device, timer_work.work); struct mei_device, timer_work.work);
bool reschedule_timer = false;
mutex_lock(&dev->device_lock); mutex_lock(&dev->device_lock);
...@@ -486,6 +498,7 @@ void mei_timer(struct work_struct *work) ...@@ -486,6 +498,7 @@ void mei_timer(struct work_struct *work)
mei_reset(dev); mei_reset(dev);
goto out; goto out;
} }
reschedule_timer = true;
} }
} }
...@@ -500,6 +513,7 @@ void mei_timer(struct work_struct *work) ...@@ -500,6 +513,7 @@ void mei_timer(struct work_struct *work)
mei_connect_timeout(cl); mei_connect_timeout(cl);
goto out; goto out;
} }
reschedule_timer = true;
} }
} }
...@@ -512,11 +526,14 @@ void mei_timer(struct work_struct *work) ...@@ -512,11 +526,14 @@ void mei_timer(struct work_struct *work)
mei_reset(dev); mei_reset(dev);
mei_amthif_run_next_cmd(dev); mei_amthif_run_next_cmd(dev);
goto out;
} }
reschedule_timer = true;
} }
out: out:
if (dev->dev_state != MEI_DEV_DISABLED) if (dev->dev_state != MEI_DEV_DISABLED && reschedule_timer)
schedule_delayed_work(&dev->timer_work, 2 * HZ); mei_schedule_stall_timer(dev);
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
} }
...@@ -548,6 +548,7 @@ void mei_cancel_work(struct mei_device *dev); ...@@ -548,6 +548,7 @@ void mei_cancel_work(struct mei_device *dev);
*/ */
void mei_timer(struct work_struct *work); void mei_timer(struct work_struct *work);
void mei_schedule_stall_timer(struct mei_device *dev);
int mei_irq_read_handler(struct mei_device *dev, int mei_irq_read_handler(struct mei_device *dev,
struct mei_cl_cb *cmpl_list, s32 *slots); struct mei_cl_cb *cmpl_list, s32 *slots);
......
...@@ -220,8 +220,6 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -220,8 +220,6 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
schedule_delayed_work(&dev->timer_work, HZ);
/* /*
* For not wake-able HW runtime pm framework * For not wake-able HW runtime pm framework
* can't be used on pci device level. * can't be used on pci device level.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册