therm_throt.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. /*
  2. * linux/arch/i386/kerne/cpu/mcheck/therm_throt.c
  3. *
  4. * Thermal throttle event support code.
  5. *
  6. * Author: Dmitriy Zavin (dmitriyz@google.com)
  7. *
  8. * Credits: Adapted from Zwane Mwaikambo's original code in mce_intel.c.
  9. *
  10. */
  11. #include <linux/percpu.h>
  12. #include <linux/cpu.h>
  13. #include <asm/cpu.h>
  14. #include <linux/notifier.h>
  15. #include <asm/therm_throt.h>
  16. /* How long to wait between reporting thermal events */
  17. #define CHECK_INTERVAL (300 * HZ)
  18. static DEFINE_PER_CPU(__u64, next_check);
  19. /***
  20. * therm_throt_process - Process thermal throttling event
  21. * @curr: Whether the condition is current or not (boolean), since the
  22. * thermal interrupt normally gets called both when the thermal
  23. * event begins and once the event has ended.
  24. *
  25. * This function is normally called by the thermal interrupt after the
  26. * IRQ has been acknowledged.
  27. *
  28. * It will take care of rate limiting and printing messages to the syslog.
  29. *
  30. * Returns: 0 : Event should NOT be further logged, i.e. still in
  31. * "timeout" from previous log message.
  32. * 1 : Event should be logged further, and a message has been
  33. * printed to the syslog.
  34. */
  35. int therm_throt_process(int curr)
  36. {
  37. unsigned int cpu = smp_processor_id();
  38. __u64 tmp_jiffs = get_jiffies_64();
  39. if (time_before64(tmp_jiffs, __get_cpu_var(next_check)))
  40. return 0;
  41. __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL;
  42. /* if we just entered the thermal event */
  43. if (curr) {
  44. printk(KERN_CRIT "CPU%d: Temperature above threshold, "
  45. "cpu clock throttled\n", cpu);
  46. add_taint(TAINT_MACHINE_CHECK);
  47. } else {
  48. printk(KERN_CRIT "CPU%d: Temperature/speed normal\n", cpu);
  49. }
  50. return 1;
  51. }