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: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
6eb1c9496b
commit
1892fc2ee4
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -548,6 +548,7 @@ void mei_cancel_work(struct mei_device *dev);
|
|||
*/
|
||||
|
||||
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,
|
||||
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)
|
|||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
schedule_delayed_work(&dev->timer_work, HZ);
|
||||
|
||||
/*
|
||||
* For not wake-able HW runtime pm framework
|
||||
* can't be used on pci device level.
|
||||
|
|
Loading…
Reference in New Issue