#include #include #include #include #include #define BLKHASHPROF _IOR(0x12,108,sizeof(struct bio_hash_stats)) #define BLKHASHCLEAR _IO(0x12,109) #define MAX_PROFILE_BUCKETS 64 struct bio_hash_stats { unsigned long nr_lookups; unsigned long nr_hits; unsigned long nr_inserts; unsigned long max_bucket_size; unsigned long bucket_size[MAX_PROFILE_BUCKETS + 1]; unsigned long q_nr_back_lookups; unsigned long q_nr_back_hits; unsigned long q_nr_back_merges; unsigned long q_nr_front_lookups; unsigned long q_nr_front_hits; unsigned long q_nr_front_merges; }; int main(int argc, char *argv[]) { struct bio_hash_stats *stat; int fd, i, c, reset = 0; float hitrate; if (argc < 2) { fprintf(stderr, "need device as argument\n"); return 1; } fprintf(stdout, "Using device %s\n", argv[1]); fd = open(argv[1], O_RDONLY); if (fd == -1) { perror("open"); return 2; } for (;;) { c = getopt(argc, argv, "r"); if (c == -1) break; switch (c) { case 'r': reset = 1; break; default: break; } } if (reset) { fprintf(stdout, "Clearing hash statistics\n"); if (ioctl(fd, BLKHASHCLEAR) == -1) { perror("ioctl"); return 3; } return 0; } stat = malloc(sizeof(struct bio_hash_stats)); if (ioctl(fd, BLKHASHPROF, stat) == -1) { perror("ioctl"); return 3; } fprintf(stdout, "Nr lookups\t\t%lu\n", stat->nr_lookups); fprintf(stdout, "Nr hits\t\t\t%lu\n", stat->nr_hits); fprintf(stdout, "Nr inserts\t\t%lu\n\n", stat->nr_inserts); fprintf(stdout, "Nr back lookups\t\t%lu\n", stat->q_nr_back_lookups); fprintf(stdout, "Nr back hits\t\t%lu\n", stat->q_nr_back_hits); fprintf(stdout, "Nr back merges\t\t%lu\n", stat->q_nr_back_merges); hitrate = 100.0; if (stat->q_nr_back_lookups) hitrate = (stat->q_nr_back_merges * 100.0) / stat->q_nr_back_lookups; fprintf(stdout, "Hit rate\t\t%.02f%%\n\n", hitrate); fprintf(stdout, "Nr front lookups\t%lu\n", stat->q_nr_front_lookups); fprintf(stdout, "Nr front hits\t\t%lu\n", stat->q_nr_front_hits); fprintf(stdout, "Nr front merges\t\t%lu\n", stat->q_nr_front_merges); hitrate = 100.0; if (stat->q_nr_front_lookups) hitrate = (stat->q_nr_front_merges * 100.0) / stat->q_nr_front_lookups; fprintf(stdout, "Hit rate\t\t%.02f%%\n\n", hitrate); fprintf(stdout, "Max fill\t\t%lu\n", stat->max_bucket_size + 1); fprintf(stdout, "Fill distribution over time:\n"); for (i = 0; i <= MAX_PROFILE_BUCKETS && i <= stat->max_bucket_size; i++) fprintf(stdout, "%02d: %lu\n", i + 1, stat->bucket_size[i]); return 0; }