perfmon_types.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright (c) 2014-2018 Remy Noel.
  3. * Copyright (c) 2014-2018 Richard Braun.
  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 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. *
  19. * Isolated type definitions used to avoid inclusion circular dependencies.
  20. */
  21. #ifndef KERN_PERFMON_TYPES_H
  22. #define KERN_PERFMON_TYPES_H
  23. #ifdef CONFIG_PERFMON
  24. #include <stdbool.h>
  25. #include <stdint.h>
  26. #include <kern/spinlock_types.h>
  27. // Maximum number of supported hardware counters.
  28. #define PERFMON_MAX_PMCS CONFIG_PERFMON_MAX_PMCS
  29. /*
  30. * Performance monitoring event.
  31. *
  32. * An event may be unattached, attached to a thread, or attached to a CPU.
  33. * When it is loaded, the current value of the underlying PMC is saved.
  34. * When it is updated, the delta between the current and saved PMC values
  35. * is added to the event value.
  36. */
  37. struct perfmon_event
  38. {
  39. struct spinlock lock;
  40. unsigned int flags;
  41. unsigned int id;
  42. uint64_t pmc_value;
  43. uint64_t value;
  44. union
  45. {
  46. struct thread *thread;
  47. unsigned int cpu;
  48. };
  49. unsigned int pmc_index;
  50. };
  51. /*
  52. * Per-thread performance monitoring counter.
  53. *
  54. * Per-thread PMCs are indexed the same way as global PMCs.
  55. *
  56. * A per-thread PMC is referenced when an event is attached to a thread.
  57. * The PMC may only be loaded if the thread is running on a processor,
  58. * as a result of an event being attached to the thread, or the thread
  59. * being dispatched by the scheduler. Note that this allows a transient
  60. * state to be seen where a per-thread PMC is both unused and loaded.
  61. * This happens after detaching an event from a thread, resulting in
  62. * the underlying per-thread PMC to become unused, but if the thread
  63. * is running concurrently, the counter is still loaded. The implementation
  64. * resolves the situation by unloading the counter, which is either
  65. * done by an explicit unload cross-call, or when the scheduler preempts
  66. * the thread and unloads its thread data.
  67. *
  68. * When a per-thread PMC is loaded, the current value of the underlying
  69. * PMC is saved, and when it's updated, the delta between the current
  70. * and saved PMC values is added to the per-thread PMC value.
  71. */
  72. struct perfmon_td_pmc
  73. {
  74. unsigned int nr_refs;
  75. bool loaded;
  76. unsigned int pmc_id;
  77. unsigned int raw_event_id;
  78. uint64_t cpu_pmc_value;
  79. uint64_t value;
  80. };
  81. /*
  82. * Per-thread performance monitoring data.
  83. *
  84. * Interrupts must be disabled when locking thread data.
  85. */
  86. struct perfmon_td
  87. {
  88. struct spinlock lock;
  89. struct perfmon_td_pmc pmcs[PERFMON_MAX_PMCS];
  90. };
  91. #endif // CONFIG_PERFMON
  92. #endif