• R/O
  • HTTP
  • SSH
  • HTTPS

linux-2.4.36: コミット

2.4.36-stable kernel tree


コミットメタ情報

リビジョン55cf1ddbffe17586bdb585647e53c44c92e900b1 (tree)
日時2006-09-29 06:10:27
作者Steffen Maier <smaier@user...>
コミッターWilly Tarreau

ログメッセージ

[PATCH] block: fix negative bias of ios_in_flight (CONFIG_BLK_STATS) because of unbalanced I/O accounting

Fix for unbalanced I/O accounting, that caused ios_in_flight
(CONFIG_BLK_STATS) to become and stay negative, as suggested by Jens
Axboe.

An added boolean field "io_account" in struct request is assumed to be
initialized to false on new requests. On starting I/O accounting, true is
assigned to the field. On ending I/O accounting, accounting is only
executed if the field has already been assigned true previously. Thus,
this fixes unbalanced cases where requests such as non-data get enqueued
without starting to account (ide_do_drive_cmd?) but the end of accounting
gets executed on finishing the same requests (ide_end_drive_cmd,
end_that_request_last, req_finished_io).

The precondition of io_account being initialized to false is ensured by

1) ide_init_drive_taskfile / ide_init_drive_cmd memset'ing the whole
request to zero, for requests that were potentially accounted unbalanced,
and

2) get_request assigning zero to io_account on allocating a request from
the free list cache (or slab cache initially), for the majority of
requests such as those involving data.

Jens preferred this to other discussed solutions and it should fix all
those unbalanced cases at once without touching each of them individually.

For more details, please see previous posts of this thread
http://www.uwsg.iu.edu/hypermail/linux/kernel/0608.2/0776.html.

I tested the patch with 2.4.24 and 2.4.33.3 successfully on an UP ia32
machine with one /dev/hda.

Signed-off-by: Steffen Maier <smaier@users.sourceforge.net>

変更サマリ

差分

--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -575,6 +575,7 @@ static struct request *get_request(request_queue_t *q, int rw)
575575 rq->rq_status = RQ_ACTIVE;
576576 rq->cmd = rw;
577577 rq->special = NULL;
578+ rq->io_account = 0;
578579 rq->q = q;
579580 }
580581
@@ -813,6 +814,7 @@ void req_new_io(struct request *req, int merge, int sectors)
813814 struct hd_struct *hd1, *hd2;
814815
815816 locate_hd_struct(req, &hd1, &hd2);
817+ req->io_account = 1;
816818 if (hd1)
817819 account_io_start(hd1, req, merge, sectors);
818820 if (hd2)
@@ -823,6 +825,8 @@ void req_merged_io(struct request *req)
823825 {
824826 struct hd_struct *hd1, *hd2;
825827
828+ if (unlikely(req->io_account == 0))
829+ return;
826830 locate_hd_struct(req, &hd1, &hd2);
827831 if (hd1)
828832 down_ios(hd1);
@@ -834,6 +838,8 @@ void req_finished_io(struct request *req)
834838 {
835839 struct hd_struct *hd1, *hd2;
836840
841+ if (unlikely(req->io_account == 0))
842+ return;
837843 locate_hd_struct(req, &hd1, &hd2);
838844 if (hd1)
839845 account_io_end(hd1, req);
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -46,6 +46,7 @@ struct request {
4646 struct buffer_head * bh;
4747 struct buffer_head * bhtail;
4848 request_queue_t *q;
49+ char io_account;
4950 };
5051
5152 #include <linux/elevator.h>
旧リポジトリブラウザで表示