diff options
author | Alexander Usyskin <alexander.usyskin@intel.com> | 2016-09-25 06:25:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-09-27 06:33:47 -0400 |
commit | 1892fc2ee4c08d7ac17adb93f1341d9c3d7bdaf6 (patch) | |
tree | d4ab5c7663479092db1fa3308ded6f82cbe253cc /drivers/misc | |
parent | 6eb1c9496b81680f2cd2e0eda06c531317e2e28d (diff) |
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>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/mei/amthif.c | 1 | ||||
-rw-r--r-- | drivers/misc/mei/client.c | 2 | ||||
-rw-r--r-- | drivers/misc/mei/hbm.c | 3 | ||||
-rw-r--r-- | drivers/misc/mei/init.c | 2 | ||||
-rw-r--r-- | drivers/misc/mei/interrupt.c | 25 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 1 | ||||
-rw-r--r-- | drivers/misc/mei/pci-me.c | 2 |
7 files changed, 29 insertions, 7 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 082462ea90c9..7ae89b4a21d5 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c | |||
@@ -277,6 +277,7 @@ void mei_amthif_complete(struct mei_cl *cl, struct mei_cl_cb *cb) | |||
277 | case MEI_FOP_WRITE: | 277 | case MEI_FOP_WRITE: |
278 | if (!cb->status) { | 278 | if (!cb->status) { |
279 | dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; | 279 | dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; |
280 | mei_schedule_stall_timer(dev); | ||
280 | mei_io_cb_free(cb); | 281 | mei_io_cb_free(cb); |
281 | return; | 282 | return; |
282 | } | 283 | } |
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 45a7652820cf..6fe02350578d 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -826,6 +826,7 @@ static int mei_cl_send_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb) | |||
826 | 826 | ||
827 | list_move_tail(&cb->list, &dev->ctrl_rd_list.list); | 827 | list_move_tail(&cb->list, &dev->ctrl_rd_list.list); |
828 | cl->timer_count = MEI_CONNECT_TIMEOUT; | 828 | cl->timer_count = MEI_CONNECT_TIMEOUT; |
829 | mei_schedule_stall_timer(dev); | ||
829 | 830 | ||
830 | return 0; | 831 | return 0; |
831 | } | 832 | } |
@@ -1011,6 +1012,7 @@ static int mei_cl_send_connect(struct mei_cl *cl, struct mei_cl_cb *cb) | |||
1011 | 1012 | ||
1012 | list_move_tail(&cb->list, &dev->ctrl_rd_list.list); | 1013 | list_move_tail(&cb->list, &dev->ctrl_rd_list.list); |
1013 | cl->timer_count = MEI_CONNECT_TIMEOUT; | 1014 | cl->timer_count = MEI_CONNECT_TIMEOUT; |
1015 | mei_schedule_stall_timer(dev); | ||
1014 | return 0; | 1016 | return 0; |
1015 | } | 1017 | } |
1016 | 1018 | ||
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 4b9495f0394c..dd7f15a65eed 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c | |||
@@ -277,6 +277,7 @@ int mei_hbm_start_req(struct mei_device *dev) | |||
277 | 277 | ||
278 | dev->hbm_state = MEI_HBM_STARTING; | 278 | dev->hbm_state = MEI_HBM_STARTING; |
279 | dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; | 279 | dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; |
280 | mei_schedule_stall_timer(dev); | ||
280 | return 0; | 281 | return 0; |
281 | } | 282 | } |
282 | 283 | ||
@@ -312,6 +313,7 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev) | |||
312 | } | 313 | } |
313 | dev->hbm_state = MEI_HBM_ENUM_CLIENTS; | 314 | dev->hbm_state = MEI_HBM_ENUM_CLIENTS; |
314 | dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; | 315 | dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; |
316 | mei_schedule_stall_timer(dev); | ||
315 | return 0; | 317 | return 0; |
316 | } | 318 | } |
317 | 319 | ||
@@ -562,6 +564,7 @@ static int mei_hbm_prop_req(struct mei_device *dev, unsigned long start_idx) | |||
562 | } | 564 | } |
563 | 565 | ||
564 | dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; | 566 | dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; |
567 | mei_schedule_stall_timer(dev); | ||
565 | 568 | ||
566 | return 0; | 569 | return 0; |
567 | } | 570 | } |
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index f7c8dfdb6a12..9a9c2484d107 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c | |||
@@ -94,7 +94,7 @@ void mei_cancel_work(struct mei_device *dev) | |||
94 | cancel_work_sync(&dev->reset_work); | 94 | cancel_work_sync(&dev->reset_work); |
95 | cancel_work_sync(&dev->bus_rescan_work); | 95 | cancel_work_sync(&dev->bus_rescan_work); |
96 | 96 | ||
97 | cancel_delayed_work(&dev->timer_work); | 97 | cancel_delayed_work_sync(&dev->timer_work); |
98 | } | 98 | } |
99 | EXPORT_SYMBOL_GPL(mei_cancel_work); | 99 | EXPORT_SYMBOL_GPL(mei_cancel_work); |
100 | 100 | ||
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index bf745e03f21e..5a4893ce9c24 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c | |||
@@ -459,6 +459,19 @@ static void mei_connect_timeout(struct mei_cl *cl) | |||
459 | mei_reset(dev); | 459 | mei_reset(dev); |
460 | } | 460 | } |
461 | 461 | ||
462 | #define MEI_STALL_TIMER_FREQ (2 * HZ) | ||
463 | /** | ||
464 | * mei_schedule_stall_timer - re-arm stall_timer work | ||
465 | * | ||
466 | * Schedule stall timer | ||
467 | * | ||
468 | * @dev: the device structure | ||
469 | */ | ||
470 | void mei_schedule_stall_timer(struct mei_device *dev) | ||
471 | { | ||
472 | schedule_delayed_work(&dev->timer_work, MEI_STALL_TIMER_FREQ); | ||
473 | } | ||
474 | |||
462 | /** | 475 | /** |
463 | * mei_timer - timer function. | 476 | * mei_timer - timer function. |
464 | * | 477 | * |
@@ -468,10 +481,9 @@ static void mei_connect_timeout(struct mei_cl *cl) | |||
468 | void mei_timer(struct work_struct *work) | 481 | void mei_timer(struct work_struct *work) |
469 | { | 482 | { |
470 | struct mei_cl *cl; | 483 | struct mei_cl *cl; |
471 | |||
472 | struct mei_device *dev = container_of(work, | 484 | struct mei_device *dev = container_of(work, |
473 | struct mei_device, timer_work.work); | 485 | struct mei_device, timer_work.work); |
474 | 486 | bool reschedule_timer = false; | |
475 | 487 | ||
476 | mutex_lock(&dev->device_lock); | 488 | mutex_lock(&dev->device_lock); |
477 | 489 | ||
@@ -486,6 +498,7 @@ void mei_timer(struct work_struct *work) | |||
486 | mei_reset(dev); | 498 | mei_reset(dev); |
487 | goto out; | 499 | goto out; |
488 | } | 500 | } |
501 | reschedule_timer = true; | ||
489 | } | 502 | } |
490 | } | 503 | } |
491 | 504 | ||
@@ -500,6 +513,7 @@ void mei_timer(struct work_struct *work) | |||
500 | mei_connect_timeout(cl); | 513 | mei_connect_timeout(cl); |
501 | goto out; | 514 | goto out; |
502 | } | 515 | } |
516 | reschedule_timer = true; | ||
503 | } | 517 | } |
504 | } | 518 | } |
505 | 519 | ||
@@ -512,11 +526,14 @@ void mei_timer(struct work_struct *work) | |||
512 | mei_reset(dev); | 526 | mei_reset(dev); |
513 | 527 | ||
514 | mei_amthif_run_next_cmd(dev); | 528 | mei_amthif_run_next_cmd(dev); |
529 | goto out; | ||
515 | } | 530 | } |
531 | reschedule_timer = true; | ||
516 | } | 532 | } |
517 | 533 | ||
518 | out: | 534 | out: |
519 | if (dev->dev_state != MEI_DEV_DISABLED) | 535 | if (dev->dev_state != MEI_DEV_DISABLED && reschedule_timer) |
520 | schedule_delayed_work(&dev->timer_work, 2 * HZ); | 536 | mei_schedule_stall_timer(dev); |
537 | |||
521 | mutex_unlock(&dev->device_lock); | 538 | mutex_unlock(&dev->device_lock); |
522 | } | 539 | } |
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 397ae2b45c9e..1169fd9e7d02 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h | |||
@@ -548,6 +548,7 @@ void mei_cancel_work(struct mei_device *dev); | |||
548 | */ | 548 | */ |
549 | 549 | ||
550 | void mei_timer(struct work_struct *work); | 550 | void mei_timer(struct work_struct *work); |
551 | void mei_schedule_stall_timer(struct mei_device *dev); | ||
551 | int mei_irq_read_handler(struct mei_device *dev, | 552 | int mei_irq_read_handler(struct mei_device *dev, |
552 | struct mei_cl_cb *cmpl_list, s32 *slots); | 553 | struct mei_cl_cb *cmpl_list, s32 *slots); |
553 | 554 | ||
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index e85bb371c87d..f3ffd883b232 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c | |||
@@ -220,8 +220,6 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
220 | 220 | ||
221 | pci_set_drvdata(pdev, dev); | 221 | pci_set_drvdata(pdev, dev); |
222 | 222 | ||
223 | schedule_delayed_work(&dev->timer_work, HZ); | ||
224 | |||
225 | /* | 223 | /* |
226 | * For not wake-able HW runtime pm framework | 224 | * For not wake-able HW runtime pm framework |
227 | * can't be used on pci device level. | 225 | * can't be used on pci device level. |