uw-vmstats.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* UW specific code - This won't be needed or used until assignment 3 */
  2. /* belongs in kern/vm/uw-vmstats.c */
  3. /* NOTE !!!!!! WARNING !!!!!
  4. * All of the functions whose names begin with '_'
  5. * assume that atomicity is ensured elsewhere
  6. * (i.e., outside of these routines) by acquiring stats_lock.
  7. * All of the functions whose names do not begin
  8. * with '_' ensure atomicity locally.
  9. */
  10. #include <types.h>
  11. #include <lib.h>
  12. #include <synch.h>
  13. #include <spl.h>
  14. #include <uw-vmstats.h>
  15. /* Counters for tracking statistics */
  16. static unsigned int stats_counts[VMSTAT_COUNT];
  17. struct spinlock stats_lock = SPINLOCK_INITIALIZER;
  18. /* Strings used in printing out the statistics */
  19. static const char *stats_names[] = {
  20. /* 0 */ "TLB Faults",
  21. /* 1 */ "TLB Faults with Free",
  22. /* 2 */ "TLB Faults with Replace",
  23. /* 3 */ "TLB Invalidations",
  24. /* 4 */ "TLB Reloads",
  25. /* 5 */ "Page Faults (Zeroed)",
  26. /* 6 */ "Page Faults (Disk)",
  27. /* 7 */ "Page Faults from ELF",
  28. /* 8 */ "Page Faults from Swapfile",
  29. /* 9 */ "Swapfile Writes",
  30. };
  31. /* ---------------------------------------------------------------------- */
  32. /* Assumes vmstat_init has already been called */
  33. void
  34. vmstats_inc(unsigned int index)
  35. {
  36. spinlock_acquire(&stats_lock);
  37. _vmstats_inc(index);
  38. spinlock_release(&stats_lock);
  39. }
  40. /* ---------------------------------------------------------------------- */
  41. void
  42. vmstats_init(void)
  43. {
  44. /* Although the spinlock is initialized at declaration time we do it here
  45. * again in case we want use/reset these stats repeatedly without shutting down the kernel.
  46. */
  47. spinlock_init(&stats_lock);
  48. spinlock_acquire(&stats_lock);
  49. _vmstats_init();
  50. spinlock_release(&stats_lock);
  51. }
  52. /* ---------------------------------------------------------------------- */
  53. void
  54. _vmstats_inc(unsigned int index)
  55. {
  56. KASSERT(index < VMSTAT_COUNT);
  57. stats_counts[index]++;
  58. }
  59. /* ---------------------------------------------------------------------- */
  60. void
  61. _vmstats_init(void)
  62. {
  63. int i = 0;
  64. if (sizeof(stats_names) / sizeof(char *) != VMSTAT_COUNT) {
  65. kprintf("vmstats_init: number of stats_names = %d != VMSTAT_COUNT = %d\n",
  66. (sizeof(stats_names) / sizeof(char *)), VMSTAT_COUNT);
  67. panic("Should really fix this before proceeding\n");
  68. }
  69. for (i=0; i<VMSTAT_COUNT; i++) {
  70. stats_counts[i] = 0;
  71. }
  72. }
  73. /* ---------------------------------------------------------------------- */
  74. /* Assumes vmstat_init has already been called */
  75. /* NOTE: We do not grab the spinlock here because kprintf may block
  76. * and we can't block while holding a spinlock.
  77. * Just use this when there is only one thread remaining.
  78. */
  79. void
  80. vmstats_print(void)
  81. {
  82. int i = 0;
  83. int free_plus_replace = 0;
  84. int disk_plus_zeroed_plus_reload = 0;
  85. int tlb_faults = 0;
  86. int elf_plus_swap_reads = 0;
  87. int disk_reads = 0;
  88. kprintf("VMSTATS:\n");
  89. for (i=0; i<VMSTAT_COUNT; i++) {
  90. kprintf("VMSTAT %25s = %10d\n", stats_names[i], stats_counts[i]);
  91. }
  92. tlb_faults = stats_counts[VMSTAT_TLB_FAULT];
  93. free_plus_replace = stats_counts[VMSTAT_TLB_FAULT_FREE] + stats_counts[VMSTAT_TLB_FAULT_REPLACE];
  94. disk_plus_zeroed_plus_reload = stats_counts[VMSTAT_PAGE_FAULT_DISK] +
  95. stats_counts[VMSTAT_PAGE_FAULT_ZERO] + stats_counts[VMSTAT_TLB_RELOAD];
  96. elf_plus_swap_reads = stats_counts[VMSTAT_ELF_FILE_READ] + stats_counts[VMSTAT_SWAP_FILE_READ];
  97. disk_reads = stats_counts[VMSTAT_PAGE_FAULT_DISK];
  98. kprintf("VMSTAT TLB Faults with Free + TLB Faults with Replace = %d\n", free_plus_replace);
  99. if (tlb_faults != free_plus_replace) {
  100. kprintf("WARNING: TLB Faults (%d) != TLB Faults with Free + TLB Faults with Replace (%d)\n",
  101. tlb_faults, free_plus_replace);
  102. }
  103. kprintf("VMSTAT TLB Reloads + Page Faults (Zeroed) + Page Faults (Disk) = %d\n",
  104. disk_plus_zeroed_plus_reload);
  105. if (tlb_faults != disk_plus_zeroed_plus_reload) {
  106. kprintf("WARNING: TLB Faults (%d) != TLB Reloads + Page Faults (Zeroed) + Page Faults (Disk) (%d)\n",
  107. tlb_faults, disk_plus_zeroed_plus_reload);
  108. }
  109. kprintf("VMSTAT ELF File reads + Swapfile reads = %d\n", elf_plus_swap_reads);
  110. if (disk_reads != elf_plus_swap_reads) {
  111. kprintf("WARNING: ELF File reads + Swapfile reads != Page Faults (Disk) %d\n",
  112. elf_plus_swap_reads);
  113. }
  114. }
  115. /* ---------------------------------------------------------------------- */