Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 196804
b: refs/heads/master
c: 812d402
h: refs/heads/master
v: v3
  • Loading branch information
Divyesh Shah authored and Jens Axboe committed Apr 9, 2010
1 parent 500ed7d commit 7cd8e0e
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 84c124da9ff50bd71fab9c939ee5b7cd8bef2bd9
refs/heads/master: 812d402648f4fc1ab1091b2172a46fc1b367c724
5 changes: 5 additions & 0 deletions trunk/Documentation/cgroups/blkio-controller.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ Details of cgroup files
minor number of the device, third field specifies the operation type
and the fourth field specifies the io_wait_time in ns.

- blkio.io_merged
- Total number of bios/requests merged into requests belonging to this
cgroup. This is further divided by the type of operation - read or
write, sync or async.

- blkio.dequeue
- Debugging aid only enabled if CONFIG_DEBUG_CFQ_IOSCHED=y. This
gives the statistics about how many a times a group was dequeued
Expand Down
17 changes: 17 additions & 0 deletions trunk/block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@ void blkiocg_update_completion_stats(struct blkio_group *blkg,
}
EXPORT_SYMBOL_GPL(blkiocg_update_completion_stats);

void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction,
bool sync)
{
unsigned long flags;

spin_lock_irqsave(&blkg->stats_lock, flags);
blkio_add_stat(blkg->stats.stat_arr[BLKIO_STAT_MERGED], 1, direction,
sync);
spin_unlock_irqrestore(&blkg->stats_lock, flags);
}
EXPORT_SYMBOL_GPL(blkiocg_update_io_merged_stats);

void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
struct blkio_group *blkg, void *key, dev_t dev)
{
Expand Down Expand Up @@ -363,6 +375,7 @@ SHOW_FUNCTION_PER_GROUP(io_service_bytes, BLKIO_STAT_SERVICE_BYTES, 1);
SHOW_FUNCTION_PER_GROUP(io_serviced, BLKIO_STAT_SERVICED, 1);
SHOW_FUNCTION_PER_GROUP(io_service_time, BLKIO_STAT_SERVICE_TIME, 1);
SHOW_FUNCTION_PER_GROUP(io_wait_time, BLKIO_STAT_WAIT_TIME, 1);
SHOW_FUNCTION_PER_GROUP(io_merged, BLKIO_STAT_MERGED, 1);
#ifdef CONFIG_DEBUG_BLK_CGROUP
SHOW_FUNCTION_PER_GROUP(dequeue, BLKIO_STAT_DEQUEUE, 0);
#endif
Expand Down Expand Up @@ -407,6 +420,10 @@ struct cftype blkio_files[] = {
.name = "io_wait_time",
.read_map = blkiocg_io_wait_time_read,
},
{
.name = "io_merged",
.read_map = blkiocg_io_merged_read,
},
{
.name = "reset_stats",
.write_u64 = blkiocg_reset_stats,
Expand Down
8 changes: 7 additions & 1 deletion trunk/block/blk-cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ enum stat_type {
BLKIO_STAT_SERVICED,
/* Total time spent waiting in scheduler queue in ns */
BLKIO_STAT_WAIT_TIME,
/* Number of IOs merged */
BLKIO_STAT_MERGED,
/* All the single valued stats go below this */
BLKIO_STAT_TIME,
BLKIO_STAT_SECTORS,
Expand Down Expand Up @@ -61,7 +63,7 @@ struct blkio_group_stats {
/* total disk time and nr sectors dispatched by this group */
uint64_t time;
uint64_t sectors;
uint64_t stat_arr[BLKIO_STAT_WAIT_TIME + 1][BLKIO_STAT_TOTAL];
uint64_t stat_arr[BLKIO_STAT_MERGED + 1][BLKIO_STAT_TOTAL];
#ifdef CONFIG_DEBUG_BLK_CGROUP
/* How many times this group has been removed from service tree */
unsigned long dequeue;
Expand Down Expand Up @@ -148,6 +150,8 @@ void blkiocg_update_dispatch_stats(struct blkio_group *blkg, uint64_t bytes,
bool direction, bool sync);
void blkiocg_update_completion_stats(struct blkio_group *blkg,
uint64_t start_time, uint64_t io_start_time, bool direction, bool sync);
void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction,
bool sync);
#else
struct cgroup;
static inline struct blkio_cgroup *
Expand All @@ -169,5 +173,7 @@ static inline void blkiocg_update_dispatch_stats(struct blkio_group *blkg,
static inline void blkiocg_update_completion_stats(struct blkio_group *blkg,
uint64_t start_time, uint64_t io_start_time, bool direction,
bool sync) {}
static inline void blkiocg_update_io_merged_stats(struct blkio_group *blkg,
bool direction, bool sync) {}
#endif
#endif /* _BLK_CGROUP_H */
2 changes: 2 additions & 0 deletions trunk/block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
if (!blk_rq_cpu_valid(req))
req->cpu = bio->bi_comp_cpu;
drive_stat_acct(req, 0);
elv_bio_merged(q, req, bio);
if (!attempt_back_merge(q, req))
elv_merged_request(q, req, el_ret);
goto out;
Expand Down Expand Up @@ -1235,6 +1236,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
if (!blk_rq_cpu_valid(req))
req->cpu = bio->bi_comp_cpu;
drive_stat_acct(req, 0);
elv_bio_merged(q, req, bio);
if (!attempt_front_merge(q, req))
elv_merged_request(q, req, el_ret);
goto out;
Expand Down
11 changes: 11 additions & 0 deletions trunk/block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -1467,6 +1467,14 @@ static void cfq_merged_request(struct request_queue *q, struct request *req,
}
}

static void cfq_bio_merged(struct request_queue *q, struct request *req,
struct bio *bio)
{
struct cfq_queue *cfqq = RQ_CFQQ(req);
blkiocg_update_io_merged_stats(&cfqq->cfqg->blkg, bio_data_dir(bio),
cfq_bio_sync(bio));
}

static void
cfq_merged_requests(struct request_queue *q, struct request *rq,
struct request *next)
Expand All @@ -1484,6 +1492,8 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
if (cfqq->next_rq == next)
cfqq->next_rq = rq;
cfq_remove_request(next);
blkiocg_update_io_merged_stats(&cfqq->cfqg->blkg, rq_data_dir(next),
rq_is_sync(next));
}

static int cfq_allow_merge(struct request_queue *q, struct request *rq,
Expand Down Expand Up @@ -3861,6 +3871,7 @@ static struct elevator_type iosched_cfq = {
.elevator_merged_fn = cfq_merged_request,
.elevator_merge_req_fn = cfq_merged_requests,
.elevator_allow_merge_fn = cfq_allow_merge,
.elevator_bio_merged_fn = cfq_bio_merged,
.elevator_dispatch_fn = cfq_dispatch_requests,
.elevator_add_req_fn = cfq_insert_request,
.elevator_activate_req_fn = cfq_activate_request,
Expand Down
9 changes: 9 additions & 0 deletions trunk/block/elevator.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,15 @@ void elv_merge_requests(struct request_queue *q, struct request *rq,
q->last_merge = rq;
}

void elv_bio_merged(struct request_queue *q, struct request *rq,
struct bio *bio)
{
struct elevator_queue *e = q->elevator;

if (e->ops->elevator_bio_merged_fn)
e->ops->elevator_bio_merged_fn(q, rq, bio);
}

void elv_requeue_request(struct request_queue *q, struct request *rq)
{
/*
Expand Down
6 changes: 6 additions & 0 deletions trunk/include/linux/elevator.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ typedef void (elevator_merged_fn) (struct request_queue *, struct request *, int

typedef int (elevator_allow_merge_fn) (struct request_queue *, struct request *, struct bio *);

typedef void (elevator_bio_merged_fn) (struct request_queue *,
struct request *, struct bio *);

typedef int (elevator_dispatch_fn) (struct request_queue *, int);

typedef void (elevator_add_req_fn) (struct request_queue *, struct request *);
Expand All @@ -36,6 +39,7 @@ struct elevator_ops
elevator_merged_fn *elevator_merged_fn;
elevator_merge_req_fn *elevator_merge_req_fn;
elevator_allow_merge_fn *elevator_allow_merge_fn;
elevator_bio_merged_fn *elevator_bio_merged_fn;

elevator_dispatch_fn *elevator_dispatch_fn;
elevator_add_req_fn *elevator_add_req_fn;
Expand Down Expand Up @@ -103,6 +107,8 @@ extern int elv_merge(struct request_queue *, struct request **, struct bio *);
extern void elv_merge_requests(struct request_queue *, struct request *,
struct request *);
extern void elv_merged_request(struct request_queue *, struct request *, int);
extern void elv_bio_merged(struct request_queue *q, struct request *,
struct bio *);
extern void elv_requeue_request(struct request_queue *, struct request *);
extern int elv_queue_empty(struct request_queue *);
extern struct request *elv_former_request(struct request_queue *, struct request *);
Expand Down

0 comments on commit 7cd8e0e

Please sign in to comment.