diff options
| author | Divyesh Shah <dpshah@google.com> | 2010-04-09 02:31:19 -0400 |
|---|---|---|
| committer | Jens Axboe <jens.axboe@oracle.com> | 2010-04-09 02:31:19 -0400 |
| commit | 84c124da9ff50bd71fab9c939ee5b7cd8bef2bd9 (patch) | |
| tree | f94ad03b56c71ebbe6b92265054c5e24af25b869 | |
| parent | 31373d09da5b7fe21fe6f781e92bd534a3495f00 (diff) | |
blkio: Changes to IO controller additional stats patches
that include some minor fixes and addresses all comments.
Changelog: (most based on Vivek Goyal's comments)
o renamed blkiocg_reset_write to blkiocg_reset_stats
o more clarification in the documentation on io_service_time and io_wait_time
o Initialize blkg->stats_lock
o rename io_add_stat to blkio_add_stat and declare it static
o use bool for direction and sync
o derive direction and sync info from existing rq methods
o use 12 for major:minor string length
o define io_service_time better to cover the NCQ case
o add a separate reset_stats interface
o make the indexed stats a 2d array to simplify macro and function pointer code
o blkio.time now exports in jiffies as before
o Added stats description in patch description and
Documentation/cgroup/blkio-controller.txt
o Prefix all stats functions with blkio and make them static as applicable
o replace IO_TYPE_MAX with IO_TYPE_TOTAL
o Moved #define constant to top of blk-cgroup.c
o Pass dev_t around instead of char *
o Add note to documentation file about resetting stats
o use BLK_CGROUP_MODULE in addition to BLK_CGROUP config option in #ifdef
statements
o Avoid struct request specific knowledge in blk-cgroup. blk-cgroup.h now has
rq_direction() and rq_sync() functions which are used by CFQ and when using
io-controller at a higher level, bio_* functions can be added.
Signed-off-by: Divyesh Shah<dpshah@google.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
| -rw-r--r-- | Documentation/cgroups/blkio-controller.txt | 48 | ||||
| -rw-r--r-- | block/blk-cgroup.c | 190 | ||||
| -rw-r--r-- | block/blk-cgroup.h | 64 | ||||
| -rw-r--r-- | block/cfq-iosched.c | 8 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 18 |
5 files changed, 198 insertions, 130 deletions
diff --git a/Documentation/cgroups/blkio-controller.txt b/Documentation/cgroups/blkio-controller.txt index 630879cd9a42..ed04fe9cce1a 100644 --- a/Documentation/cgroups/blkio-controller.txt +++ b/Documentation/cgroups/blkio-controller.txt | |||
| @@ -77,7 +77,6 @@ Details of cgroup files | |||
| 77 | ======================= | 77 | ======================= |
| 78 | - blkio.weight | 78 | - blkio.weight |
| 79 | - Specifies per cgroup weight. | 79 | - Specifies per cgroup weight. |
| 80 | |||
| 81 | Currently allowed range of weights is from 100 to 1000. | 80 | Currently allowed range of weights is from 100 to 1000. |
| 82 | 81 | ||
| 83 | - blkio.time | 82 | - blkio.time |
| @@ -92,6 +91,49 @@ Details of cgroup files | |||
| 92 | third field specifies the number of sectors transferred by the | 91 | third field specifies the number of sectors transferred by the |
| 93 | group to/from the device. | 92 | group to/from the device. |
| 94 | 93 | ||
| 94 | - blkio.io_service_bytes | ||
| 95 | - Number of bytes transferred to/from the disk by the group. These | ||
| 96 | are further divided by the type of operation - read or write, sync | ||
| 97 | or async. First two fields specify the major and minor number of the | ||
| 98 | device, third field specifies the operation type and the fourth field | ||
| 99 | specifies the number of bytes. | ||
| 100 | |||
| 101 | - blkio.io_serviced | ||
| 102 | - Number of IOs completed to/from the disk by the group. These | ||
| 103 | are further divided by the type of operation - read or write, sync | ||
| 104 | or async. First two fields specify the major and minor number of the | ||
| 105 | device, third field specifies the operation type and the fourth field | ||
| 106 | specifies the number of IOs. | ||
| 107 | |||
| 108 | - blkio.io_service_time | ||
| 109 | - Total amount of time between request dispatch and request completion | ||
| 110 | for the IOs done by this cgroup. This is in nanoseconds to make it | ||
| 111 | meaningful for flash devices too. For devices with queue depth of 1, | ||
| 112 | this time represents the actual service time. When queue_depth > 1, | ||
| 113 | that is no longer true as requests may be served out of order. This | ||
| 114 | may cause the service time for a given IO to include the service time | ||
| 115 | of multiple IOs when served out of order which may result in total | ||
| 116 | io_service_time > actual time elapsed. This time is further divided by | ||
| 117 | the type of operation - read or write, sync or async. First two fields | ||
| 118 | specify the major and minor number of the device, third field | ||
| 119 | specifies the operation type and the fourth field specifies the | ||
| 120 | io_service_time in ns. | ||
| 121 | |||
| 122 | - blkio.io_wait_time | ||
| 123 | - Total amount of time the IOs for this cgroup spent waiting in the | ||
| 124 | scheduler queues for service. This can be greater than the total time | ||
| 125 | elapsed since it is cumulative io_wait_time for all IOs. It is not a | ||
| 126 | measure of total time the cgroup spent waiting but rather a measure of | ||
| 127 | the wait_time for its individual IOs. For devices with queue_depth > 1 | ||
| 128 | this metric does not include the time spent waiting for service once | ||
| 129 | the IO is dispatched to the device but till it actually gets serviced | ||
| 130 | (there might be a time lag here due to re-ordering of requests by the | ||
| 131 | device). This is in nanoseconds to make it meaningful for flash | ||
| 132 | devices too. This time is further divided by the type of operation - | ||
| 133 | read or write, sync or async. First two fields specify the major and | ||
| 134 | minor number of the device, third field specifies the operation type | ||
| 135 | and the fourth field specifies the io_wait_time in ns. | ||
| 136 | |||
| 95 | - blkio.dequeue | 137 | - blkio.dequeue |
| 96 | - Debugging aid only enabled if CONFIG_DEBUG_CFQ_IOSCHED=y. This | 138 | - Debugging aid only enabled if CONFIG_DEBUG_CFQ_IOSCHED=y. This |
| 97 | gives the statistics about how many a times a group was dequeued | 139 | gives the statistics about how many a times a group was dequeued |
| @@ -99,6 +141,10 @@ Details of cgroup files | |||
| 99 | and minor number of the device and third field specifies the number | 141 | and minor number of the device and third field specifies the number |
| 100 | of times a group was dequeued from a particular device. | 142 | of times a group was dequeued from a particular device. |
| 101 | 143 | ||
| 144 | - blkio.reset_stats | ||
| 145 | - Writing an int to this file will result in resetting all the stats | ||
| 146 | for that cgroup. | ||
| 147 | |||
| 102 | CFQ sysfs tunable | 148 | CFQ sysfs tunable |
| 103 | ================= | 149 | ================= |
| 104 | /sys/block/<disk>/queue/iosched/group_isolation | 150 | /sys/block/<disk>/queue/iosched/group_isolation |
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 9af7257f429c..6797df508821 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #include <linux/blkdev.h> | 18 | #include <linux/blkdev.h> |
| 19 | #include "blk-cgroup.h" | 19 | #include "blk-cgroup.h" |
| 20 | 20 | ||
| 21 | #define MAX_KEY_LEN 100 | ||
| 22 | |||
| 21 | static DEFINE_SPINLOCK(blkio_list_lock); | 23 | static DEFINE_SPINLOCK(blkio_list_lock); |
| 22 | static LIST_HEAD(blkio_list); | 24 | static LIST_HEAD(blkio_list); |
| 23 | 25 | ||
| @@ -56,24 +58,27 @@ struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) | |||
| 56 | } | 58 | } |
| 57 | EXPORT_SYMBOL_GPL(cgroup_to_blkio_cgroup); | 59 | EXPORT_SYMBOL_GPL(cgroup_to_blkio_cgroup); |
| 58 | 60 | ||
| 61 | void blkio_group_init(struct blkio_group *blkg) | ||
| 62 | { | ||
| 63 | spin_lock_init(&blkg->stats_lock); | ||
| 64 | } | ||
| 65 | EXPORT_SYMBOL_GPL(blkio_group_init); | ||
| 66 | |||
| 59 | /* | 67 | /* |
| 60 | * Add to the appropriate stat variable depending on the request type. | 68 | * Add to the appropriate stat variable depending on the request type. |
| 61 | * This should be called with the blkg->stats_lock held. | 69 | * This should be called with the blkg->stats_lock held. |
| 62 | */ | 70 | */ |
| 63 | void io_add_stat(uint64_t *stat, uint64_t add, unsigned int flags) | 71 | static void blkio_add_stat(uint64_t *stat, uint64_t add, bool direction, |
| 72 | bool sync) | ||
| 64 | { | 73 | { |
| 65 | if (flags & REQ_RW) | 74 | if (direction) |
| 66 | stat[IO_WRITE] += add; | 75 | stat[BLKIO_STAT_WRITE] += add; |
| 67 | else | 76 | else |
| 68 | stat[IO_READ] += add; | 77 | stat[BLKIO_STAT_READ] += add; |
| 69 | /* | 78 | if (sync) |
| 70 | * Everywhere in the block layer, an IO is treated as sync if it is a | 79 | stat[BLKIO_STAT_SYNC] += add; |
| 71 | * read or a SYNC write. We follow the same norm. | ||
| 72 | */ | ||
| 73 | if (!(flags & REQ_RW) || flags & REQ_RW_SYNC) | ||
| 74 | stat[IO_SYNC] += add; | ||
| 75 | else | 80 | else |
| 76 | stat[IO_ASYNC] += add; | 81 | stat[BLKIO_STAT_ASYNC] += add; |
| 77 | } | 82 | } |
| 78 | 83 | ||
| 79 | void blkiocg_update_timeslice_used(struct blkio_group *blkg, unsigned long time) | 84 | void blkiocg_update_timeslice_used(struct blkio_group *blkg, unsigned long time) |
| @@ -86,23 +91,25 @@ void blkiocg_update_timeslice_used(struct blkio_group *blkg, unsigned long time) | |||
| 86 | } | 91 | } |
| 87 | EXPORT_SYMBOL_GPL(blkiocg_update_timeslice_used); | 92 | EXPORT_SYMBOL_GPL(blkiocg_update_timeslice_used); |
| 88 | 93 | ||
| 89 | void blkiocg_update_request_dispatch_stats(struct blkio_group *blkg, | 94 | void blkiocg_update_dispatch_stats(struct blkio_group *blkg, |
| 90 | struct request *rq) | 95 | uint64_t bytes, bool direction, bool sync) |
| 91 | { | 96 | { |
| 92 | struct blkio_group_stats *stats; | 97 | struct blkio_group_stats *stats; |
| 93 | unsigned long flags; | 98 | unsigned long flags; |
| 94 | 99 | ||
| 95 | spin_lock_irqsave(&blkg->stats_lock, flags); | 100 | spin_lock_irqsave(&blkg->stats_lock, flags); |
| 96 | stats = &blkg->stats; | 101 | stats = &blkg->stats; |
| 97 | stats->sectors += blk_rq_sectors(rq); | 102 | stats->sectors += bytes >> 9; |
| 98 | io_add_stat(stats->io_serviced, 1, rq->cmd_flags); | 103 | blkio_add_stat(stats->stat_arr[BLKIO_STAT_SERVICED], 1, direction, |
| 99 | io_add_stat(stats->io_service_bytes, blk_rq_sectors(rq) << 9, | 104 | sync); |
| 100 | rq->cmd_flags); | 105 | blkio_add_stat(stats->stat_arr[BLKIO_STAT_SERVICE_BYTES], bytes, |
| 106 | direction, sync); | ||
| 101 | spin_unlock_irqrestore(&blkg->stats_lock, flags); | 107 | spin_unlock_irqrestore(&blkg->stats_lock, flags); |
| 102 | } | 108 | } |
| 109 | EXPORT_SYMBOL_GPL(blkiocg_update_dispatch_stats); | ||
| 103 | 110 | ||
| 104 | void blkiocg_update_request_completion_stats(struct blkio_group *blkg, | 111 | void blkiocg_update_completion_stats(struct blkio_group *blkg, |
| 105 | struct request *rq) | 112 | uint64_t start_time, uint64_t io_start_time, bool direction, bool sync) |
| 106 | { | 113 | { |
| 107 | struct blkio_group_stats *stats; | 114 | struct blkio_group_stats *stats; |
| 108 | unsigned long flags; | 115 | unsigned long flags; |
| @@ -110,16 +117,15 @@ void blkiocg_update_request_completion_stats(struct blkio_group *blkg, | |||
| 110 | 117 | ||
| 111 | spin_lock_irqsave(&blkg->stats_lock, flags); | 118 | spin_lock_irqsave(&blkg->stats_lock, flags); |
