Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Alexander Usyskin and committed by
Greg Kroah-Hartman
1892fc2e 6eb1c949

+29 -7
+1
drivers/misc/mei/amthif.c
··· 277 277 case MEI_FOP_WRITE: 278 278 if (!cb->status) { 279 279 dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; 280 + mei_schedule_stall_timer(dev); 280 281 mei_io_cb_free(cb); 281 282 return; 282 283 }
+2
drivers/misc/mei/client.c
··· 826 826 827 827 list_move_tail(&cb->list, &dev->ctrl_rd_list.list); 828 828 cl->timer_count = MEI_CONNECT_TIMEOUT; 829 + mei_schedule_stall_timer(dev); 829 830 830 831 return 0; 831 832 } ··· 1012 1011 1013 1012 list_move_tail(&cb->list, &dev->ctrl_rd_list.list); 1014 1013 cl->timer_count = MEI_CONNECT_TIMEOUT; 1014 + mei_schedule_stall_timer(dev); 1015 1015 return 0; 1016 1016 } 1017 1017
+3
drivers/misc/mei/hbm.c
··· 277 277 278 278 dev->hbm_state = MEI_HBM_STARTING; 279 279 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 280 + mei_schedule_stall_timer(dev); 280 281 return 0; 281 282 } 282 283 ··· 313 312 } 314 313 dev->hbm_state = MEI_HBM_ENUM_CLIENTS; 315 314 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 315 + mei_schedule_stall_timer(dev); 316 316 return 0; 317 317 } 318 318 ··· 564 562 } 565 563 566 564 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 565 + mei_schedule_stall_timer(dev); 567 566 568 567 return 0; 569 568 }
+1 -1
drivers/misc/mei/init.c
··· 94 94 cancel_work_sync(&dev->reset_work); 95 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 99 EXPORT_SYMBOL_GPL(mei_cancel_work); 100 100
+21 -4
drivers/misc/mei/interrupt.c
··· 459 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 476 * mei_timer - timer function. 464 477 * ··· 481 468 void mei_timer(struct work_struct *work) 482 469 { 483 470 struct mei_cl *cl; 484 - 485 471 struct mei_device *dev = container_of(work, 486 472 struct mei_device, timer_work.work); 487 - 473 + bool reschedule_timer = false; 488 474 489 475 mutex_lock(&dev->device_lock); 490 476 ··· 498 486 mei_reset(dev); 499 487 goto out; 500 488 } 489 + reschedule_timer = true; 501 490 } 502 491 } 503 492 ··· 513 500 mei_connect_timeout(cl); 514 501 goto out; 515 502 } 503 + reschedule_timer = true; 516 504 } 517 505 } 518 506 ··· 526 512 mei_reset(dev); 527 513 528 514 mei_amthif_run_next_cmd(dev); 515 + goto out; 529 516 } 517 + reschedule_timer = true; 530 518 } 531 519 532 520 out: 533 - if (dev->dev_state != MEI_DEV_DISABLED) 534 - schedule_delayed_work(&dev->timer_work, 2 * HZ); 521 + if (dev->dev_state != MEI_DEV_DISABLED && reschedule_timer) 522 + mei_schedule_stall_timer(dev); 523 + 535 524 mutex_unlock(&dev->device_lock); 536 525 }
+1
drivers/misc/mei/mei_dev.h
··· 548 548 */ 549 549 550 550 void mei_timer(struct work_struct *work); 551 + void mei_schedule_stall_timer(struct mei_device *dev); 551 552 int mei_irq_read_handler(struct mei_device *dev, 552 553 struct mei_cl_cb *cmpl_list, s32 *slots); 553 554
-2
drivers/misc/mei/pci-me.c
··· 220 220 221 221 pci_set_drvdata(pdev, dev); 222 222 223 - schedule_delayed_work(&dev->timer_work, HZ); 224 - 225 223 /* 226 224 * For not wake-able HW runtime pm framework 227 225 * can't be used on pci device level.