diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-06-12 09:46:09 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-06-12 10:12:40 +0200 |
commit | 9f527308d7248d1ec1d63f0911757bb5faa7ea10 (patch) | |
tree | 27943302132f4b86a1ea3c6089407b45d23c66cb /cpukit/libblock/src | |
parent | libblock: Remove const qualifier (diff) | |
download | rtems-9f527308d7248d1ec1d63f0911757bb5faa7ea10.tar.bz2 |
libblock: Add block device statistics
Diffstat (limited to 'cpukit/libblock/src')
-rw-r--r-- | cpukit/libblock/src/bdbuf.c | 34 | ||||
-rw-r--r-- | cpukit/libblock/src/blkdev-blkstats.c | 70 | ||||
-rw-r--r-- | cpukit/libblock/src/blkdev-ioctl.c | 8 | ||||
-rw-r--r-- | cpukit/libblock/src/blkdev-print-stats.c | 52 |
4 files changed, 164 insertions, 0 deletions
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c index 1d683b3f89..81c8b81fb8 100644 --- a/cpukit/libblock/src/bdbuf.c +++ b/cpukit/libblock/src/bdbuf.c @@ -1899,6 +1899,21 @@ rtems_bdbuf_execute_transfer_request (rtems_disk_device *dd, rtems_bdbuf_lock_cache (); + /* Statistics */ + if (req->req == RTEMS_BLKDEV_REQ_READ) + { + dd->stats.read_blocks += req->bufnum; + if (sc != RTEMS_SUCCESSFUL) + ++dd->stats.read_errors; + } + else + { + dd->stats.write_blocks += req->bufnum; + ++dd->stats.write_transfers; + if (sc != RTEMS_SUCCESSFUL) + ++dd->stats.write_errors; + } + for (transfer_index = 0; transfer_index < req->bufnum; ++transfer_index) { rtems_bdbuf_buffer *bd = req->bufs [transfer_index].user; @@ -2074,12 +2089,15 @@ rtems_bdbuf_read (rtems_disk_device *dd, switch (bd->state) { case RTEMS_BDBUF_STATE_CACHED: + ++dd->stats.read_hits; rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_CACHED); break; case RTEMS_BDBUF_STATE_MODIFIED: + ++dd->stats.read_hits; rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_ACCESS_MODIFIED); break; case RTEMS_BDBUF_STATE_EMPTY: + ++dd->stats.read_misses; rtems_bdbuf_set_read_ahead_trigger (dd, block); sc = rtems_bdbuf_execute_read_request (dd, bd, 1); if (sc == RTEMS_SUCCESSFUL) @@ -3025,6 +3043,7 @@ rtems_bdbuf_read_ahead_task (rtems_task_argument arg) dd->read_ahead.trigger = RTEMS_DISK_READ_AHEAD_NO_TRIGGER; } + ++dd->stats.read_ahead_transfers; rtems_bdbuf_execute_read_request (dd, bd, transfer_count); } } @@ -3039,3 +3058,18 @@ rtems_bdbuf_read_ahead_task (rtems_task_argument arg) rtems_task_delete (RTEMS_SELF); } + +void rtems_bdbuf_get_device_stats (const rtems_disk_device *dd, + rtems_blkdev_stats *stats) +{ + rtems_bdbuf_lock_cache (); + *stats = dd->stats; + rtems_bdbuf_unlock_cache (); +} + +void rtems_bdbuf_reset_device_stats (rtems_disk_device *dd) +{ + rtems_bdbuf_lock_cache (); + memset (&dd->stats, 0, sizeof(dd->stats)); + rtems_bdbuf_unlock_cache (); +} diff --git a/cpukit/libblock/src/blkdev-blkstats.c b/cpukit/libblock/src/blkdev-blkstats.c new file mode 100644 index 0000000000..c870fe1080 --- /dev/null +++ b/cpukit/libblock/src/blkdev-blkstats.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include <rtems/blkdev.h> + +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> + +void rtems_blkstats(FILE *output, const char *device, bool reset) +{ + int fd = open(device, O_RDONLY); + + if (fd >= 0) { + struct stat st; + int rv; + + rv = fstat(fd, &st); + if (rv == 0) { + if (S_ISBLK(st.st_mode)) { + if (reset) { + rv = rtems_disk_fd_reset_device_stats(fd); + if (rv != 0) { + fprintf(output, "error: reset stats: %s\n", strerror(errno)); + } + } else { + rtems_blkdev_stats stats; + + rv = rtems_disk_fd_get_device_stats(fd, &stats); + if (rv == 0) { + rtems_blkdev_print_stats( + &stats, + (rtems_printk_plugin_t) fprintf, + output + ); + } else { + fprintf(output, "error: get stats: %s\n", strerror(errno)); + } + } + } else { + fprintf(output, "error: not a block device\n"); + } + } else { + fprintf(output, "error: get file stats: %s\n", strerror(errno)); + } + + rv = close(fd); + if (rv != 0) { + fprintf(output, "error: close device: %s\n", strerror(errno)); + } + } else { + fprintf(output, "error: open device: %s\n", strerror(errno)); + } +} diff --git a/cpukit/libblock/src/blkdev-ioctl.c b/cpukit/libblock/src/blkdev-ioctl.c index d775d1e833..b2215f17c2 100644 --- a/cpukit/libblock/src/blkdev-ioctl.c +++ b/cpukit/libblock/src/blkdev-ioctl.c @@ -64,6 +64,14 @@ rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp) rtems_bdbuf_purge_dev(dd); break; + case RTEMS_BLKIO_GETDEVSTATS: + rtems_bdbuf_get_device_stats(dd, (rtems_blkdev_stats *) argp); + break; + + case RTEMS_BLKIO_RESETDEVSTATS: + rtems_bdbuf_reset_device_stats(dd); + break; + default: errno = EINVAL; rc = -1; diff --git a/cpukit/libblock/src/blkdev-print-stats.c b/cpukit/libblock/src/blkdev-print-stats.c new file mode 100644 index 0000000000..8cebeaf812 --- /dev/null +++ b/cpukit/libblock/src/blkdev-print-stats.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include <rtems/blkdev.h> + +#include <inttypes.h> + +void rtems_blkdev_print_stats( + const rtems_blkdev_stats *stats, + rtems_printk_plugin_t print, + void *print_arg +) +{ + (*print)( + print_arg, + "-------------------------------------------------------------------------------\n" + " DEVICE STATISTICS\n" + "----------------------+--------------------------------------------------------\n" + " READ HITS | %" PRIu32 "\n" + " READ MISSES | %" PRIu32 "\n" + " READ AHEAD TRANSFERS | %" PRIu32 "\n" + " READ BLOCKS | %" PRIu32 "\n" + " READ ERRORS | %" PRIu32 "\n" + " WRITE TRANSFERS | %" PRIu32 "\n" + " WRITE BLOCKS | %" PRIu32 "\n" + " WRITE ERRORS | %" PRIu32 "\n" + "----------------------+--------------------------------------------------------\n", + stats->read_hits, + stats->read_misses, + stats->read_ahead_transfers, + stats->read_blocks, + stats->read_errors, + stats->write_transfers, + stats->write_blocks, + stats->write_errors + ); +} |