delayacct.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /* delayacct.c - per-task delay accounting
  2. *
  3. * Copyright (C) Shailabh Nagar, IBM Corp. 2006
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it would be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  13. * the GNU General Public License for more details.
  14. */
  15. #include <linux/sched.h>
  16. #include <linux/slab.h>
  17. #include <linux/time.h>
  18. #include <linux/sysctl.h>
  19. #include <linux/delayacct.h>
  20. int delayacct_on __read_mostly; /* Delay accounting turned on/off */
  21. kmem_cache_t *delayacct_cache;
  22. static int __init delayacct_setup_enable(char *str)
  23. {
  24. delayacct_on = 1;
  25. return 1;
  26. }
  27. __setup("delayacct", delayacct_setup_enable);
  28. void delayacct_init(void)
  29. {
  30. delayacct_cache = kmem_cache_create("delayacct_cache",
  31. sizeof(struct task_delay_info),
  32. 0,
  33. SLAB_PANIC,
  34. NULL, NULL);
  35. delayacct_tsk_init(&init_task);
  36. }
  37. void __delayacct_tsk_init(struct task_struct *tsk)
  38. {
  39. tsk->delays = kmem_cache_zalloc(delayacct_cache, SLAB_KERNEL);
  40. if (tsk->delays)
  41. spin_lock_init(&tsk->delays->lock);
  42. }
  43. void __delayacct_tsk_exit(struct task_struct *tsk)
  44. {
  45. kmem_cache_free(delayacct_cache, tsk->delays);
  46. tsk->delays = NULL;
  47. }
  48. /*
  49. * Start accounting for a delay statistic using
  50. * its starting timestamp (@start)
  51. */
  52. static inline void delayacct_start(struct timespec *start)
  53. {
  54. do_posix_clock_monotonic_gettime(start);
  55. }
  56. /*
  57. * Finish delay accounting for a statistic using
  58. * its timestamps (@start, @end), accumalator (@total) and @count
  59. */
  60. static void delayacct_end(struct timespec *start, struct timespec *end,
  61. u64 *total, u32 *count)
  62. {
  63. struct timespec ts;
  64. s64 ns;
  65. do_posix_clock_monotonic_gettime(end);
  66. ts = timespec_sub(*end, *start);
  67. ns = timespec_to_ns(&ts);
  68. if (ns < 0)
  69. return;
  70. spin_lock(&current->delays->lock);
  71. *total += ns;
  72. (*count)++;
  73. spin_unlock(&current->delays->lock);
  74. }