summaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorAlexander Usyskin <alexander.usyskin@intel.com>2016-09-25 06:25:31 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-09-27 06:33:47 -0400
commit1892fc2ee4c08d7ac17adb93f1341d9c3d7bdaf6 (patch)
treed4ab5c7663479092db1fa3308ded6f82cbe253cc /drivers/misc
parent6eb1c9496b81680f2cd2e0eda06c531317e2e28d (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.c1
-rw-r--r--drivers/misc/mei/client.c2
-rw-r--r--drivers/misc/mei/hbm.c3
-rw-r--r--drivers/misc/mei/init.c2
-rw-r--r--drivers/misc/mei/interrupt.c25
-rw-r--r--drivers/misc/mei/mei_dev.h1
-rw-r--r--drivers/misc/mei/pci-me.c2
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}
99EXPORT_SYMBOL_GPL(mei_cancel_work); 99EXPORT_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 */
470void 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)
468void mei_timer(struct work_struct *work) 481void 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
518out: 534out:
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
550void mei_timer(struct work_struct *work); 550void mei_timer(struct work_struct *work);
551void mei_schedule_stall_timer(struct mei_device *dev);
551int mei_irq_read_handler(struct mei_device *dev, 552int 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.