aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Pen <r.peniaev@gmail.com>2014-03-04 09:13:10 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-31 00:52:11 -0400
commite9d933941569c107e0083c3c115467c699a57db2 (patch)
tree38e63e8407808fcdae7e54c019fe1169a363766d
parent8d6b283d97db2d4d8fb6d1b8cfc630906f883f2f (diff)
blktrace: fix accounting of partially completed requests
commit af5040da01ef980670b3741b3e10733ee3e33566 upstream. trace_block_rq_complete does not take into account that request can be partially completed, so we can get the following incorrect output of blkparser: C R 232 + 240 [0] C R 240 + 232 [0] C R 248 + 224 [0] C R 256 + 216 [0] but should be: C R 232 + 8 [0] C R 240 + 8 [0] C R 248 + 8 [0] C R 256 + 8 [0] Also, the whole output summary statistics of completed requests and final throughput will be incorrect. This patch takes into account real completion size of the request and fixes wrong completion accounting. Signed-off-by: Roman Pen <r.peniaev@gmail.com> CC: Steven Rostedt <rostedt@goodmis.org> CC: Frederic Weisbecker <fweisbec@gmail.com> CC: Ingo Molnar <mingo@redhat.com> CC: linux-kernel@vger.kernel.org Signed-off-by: Jens Axboe <axboe@fb.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--block/blk-core.c2
-rw-r--r--include/trace/events/block.h33
-rw-r--r--kernel/trace/blktrace.c20
3 files changed, 42 insertions, 13 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 2c66daba44dd..5a750b18172e 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2299,7 +2299,7 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
2299 if (!req->bio) 2299 if (!req->bio)
2300 return false; 2300 return false;
2301 2301
2302 trace_block_rq_complete(req->q, req); 2302 trace_block_rq_complete(req->q, req, nr_bytes);
2303 2303
2304 /* 2304 /*
2305 * For fs requests, rq is just carrier of independent bio's 2305 * For fs requests, rq is just carrier of independent bio's
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index 60ae7c3db912..2e96e2bb1529 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -132,6 +132,7 @@ DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
132 * block_rq_complete - block IO operation completed by device driver 132 * block_rq_complete - block IO operation completed by device driver
133 * @q: queue containing the block operation request 133 * @q: queue containing the block operation request
134 * @rq: block operations request 134 * @rq: block operations request
135 * @nr_bytes: number of completed bytes
135 * 136 *
136 * The block_rq_complete tracepoint event indicates that some portion 137 * The block_rq_complete tracepoint event indicates that some portion
137 * of operation request has been completed by the device driver. If 138 * of operation request has been completed by the device driver. If
@@ -139,11 +140,37 @@ DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
139 * do for the request. If @rq->bio is non-NULL then there is 140 * do for the request. If @rq->bio is non-NULL then there is
140 * additional work required to complete the request. 141 * additional work required to complete the request.
141 */ 142 */
142DEFINE_EVENT(block_rq_with_error, block_rq_complete, 143TRACE_EVENT(block_rq_complete,
143 144
144 TP_PROTO(struct request_queue *q, struct request *rq), 145 TP_PROTO(struct request_queue *q, struct request *rq,
146 unsigned int nr_bytes),
145 147
146 TP_ARGS(q, rq) 148 TP_ARGS(q, rq, nr_bytes),
149
150 TP_STRUCT__entry(
151 __field( dev_t, dev )
152 __field( sector_t, sector )
153 __field( unsigned int, nr_sector )
154 __field( int, errors )
155 __array( char, rwbs, RWBS_LEN )
156 __dynamic_array( char, cmd, blk_cmd_buf_len(rq) )
157 ),
158
159 TP_fast_assign(
160 __entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
161 __entry->sector = blk_rq_pos(rq);
162 __entry->nr_sector = nr_bytes >> 9;
163 __entry->errors = rq->errors;
164
165 blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, nr_bytes);
166 blk_dump_cmd(__get_str(cmd), rq);
167 ),
168
169 TP_printk("%d,%d %s (%s) %llu + %u [%d]",
170 MAJOR(__entry->dev), MINOR(__entry->dev),
171 __entry->rwbs, __get_str(cmd),
172 (unsigned long long)__entry->sector,
173 __entry->nr_sector, __entry->errors)
147); 174);
148 175
149DECLARE_EVENT_CLASS(block_rq, 176DECLARE_EVENT_CLASS(block_rq,
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index b8b8560bfb95..686417ba5cd1 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -685,6 +685,7 @@ void blk_trace_shutdown(struct request_queue *q)
685 * blk_add_trace_rq - Add a trace for a request oriented action 685 * blk_add_trace_rq - Add a trace for a request oriented action
686 * @q: queue the io is for 686 * @q: queue the io is for
687 * @rq: the source request 687 * @rq: the source request
688 * @nr_bytes: number of completed bytes
688 * @what: the action 689 * @what: the action
689 * 690 *
690 * Description: 691 * Description:
@@ -692,7 +693,7 @@ void blk_trace_shutdown(struct request_queue *q)
692 * 693 *
693 **/ 694 **/
694static void blk_add_trace_rq(struct request_queue *q, struct request *rq, 695static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
695 u32 what) 696 unsigned int nr_bytes, u32 what)
696{ 697{
697 struct blk_trace *bt = q->blk_trace; 698 struct blk_trace *bt = q->blk_trace;
698 699
@@ -701,11 +702,11 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
701 702
702 if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { 703 if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
703 what |= BLK_TC_ACT(BLK_TC_PC); 704 what |= BLK_TC_ACT(BLK_TC_PC);
704 __blk_add_trace(bt, 0, blk_rq_bytes(rq), rq->cmd_flags, 705 __blk_add_trace(bt, 0, nr_bytes, rq->cmd_flags,
705 what, rq->errors, rq->cmd_len, rq->cmd); 706 what, rq->errors, rq->cmd_len, rq->cmd);
706 } else { 707 } else {
707 what |= BLK_TC_ACT(BLK_TC_FS); 708 what |= BLK_TC_ACT(BLK_TC_FS);
708 __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq), 709 __blk_add_trace(bt, blk_rq_pos(rq), nr_bytes,
709 rq->cmd_flags, what, rq->errors, 0, NULL); 710 rq->cmd_flags, what, rq->errors, 0, NULL);
710 } 711 }
711} 712}
@@ -713,33 +714,34 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
713static void blk_add_trace_rq_abort(void *ignore, 714static void blk_add_trace_rq_abort(void *ignore,
714 struct request_queue *q, struct request *rq) 715 struct request_queue *q, struct request *rq)
715{ 716{
716 blk_add_trace_rq(q, rq, BLK_TA_ABORT); 717 blk_add_trace_rq(q, rq, blk_rq_bytes(rq), BLK_TA_ABORT);
717} 718}
718 719
719static void blk_add_trace_rq_insert(void *ignore, 720static void blk_add_trace_rq_insert(void *ignore,
720 struct request_queue *q, struct request *rq) 721 struct request_queue *q, struct request *rq)
721{ 722{
722 blk_add_trace_rq(q, rq, BLK_TA_INSERT); 723 blk_add_trace_rq(q, rq, blk_rq_bytes(rq), BLK_TA_INSERT);
723} 724}
724 725
725static void blk_add_trace_rq_issue(void *ignore, 726static void blk_add_trace_rq_issue(void *ignore,
726 struct request_queue *q, struct request *rq) 727 struct request_queue *q, struct request *rq)
727{ 728{
728 blk_add_trace_rq(q, rq, BLK_TA_ISSUE); 729 blk_add_trace_rq(q, rq, blk_rq_bytes(rq), BLK_TA_ISSUE);
729} 730}
730 731
731static void blk_add_trace_rq_requeue(void *ignore, 732static void blk_add_trace_rq_requeue(void *ignore,
732 struct request_queue *q, 733 struct request_queue *q,
733 struct request *rq) 734 struct request *rq)
734{ 735{
735 blk_add_trace_rq(q, rq, BLK_TA_REQUEUE); 736 blk_add_trace_rq(q, rq, blk_rq_bytes(rq), BLK_TA_REQUEUE);
736} 737}
737 738
738static void blk_add_trace_rq_complete(void *ignore, 739static void blk_add_trace_rq_complete(void *ignore,
739 struct request_queue *q, 740 struct request_queue *q,
740 struct request *rq) 741 struct request *rq,
742 unsigned int nr_bytes)
741{ 743{
742 blk_add_trace_rq(q, rq, BLK_TA_COMPLETE); 744 blk_add_trace_rq(q, rq, nr_bytes, BLK_TA_COMPLETE);
743} 745}
744 746
745/** 747/**