Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
5ddfdaad
Commit
5ddfdaad
authored
Oct 28, 2002
by
Alexander Viro
Committed by
James Bottomley
Oct 28, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] IO counters - per-disk part
parent
2103a00b
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
109 additions
and
9 deletions
+109
-9
drivers/block/ll_rw_blk.c
drivers/block/ll_rw_blk.c
+59
-4
drivers/md/md.c
drivers/md/md.c
+1
-1
fs/partitions/check.c
fs/partitions/check.c
+38
-3
include/linux/blkdev.h
include/linux/blkdev.h
+1
-0
include/linux/genhd.h
include/linux/genhd.h
+10
-1
No files found.
drivers/block/ll_rw_blk.c
View file @
5ddfdaad
...
...
@@ -1414,11 +1414,17 @@ void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
return
;
if
(
rw
==
READ
)
{
rq
->
rq_disk
->
rio
+=
new_io
;
rq
->
rq_disk
->
reads
+=
nr_sectors
;
rq
->
rq_disk
->
read_sectors
+=
nr_sectors
;
if
(
!
new_io
)
rq
->
rq_disk
->
read_merges
++
;
}
else
if
(
rw
==
WRITE
)
{
rq
->
rq_disk
->
wio
+=
new_io
;
rq
->
rq_disk
->
writes
+=
nr_sectors
;
rq
->
rq_disk
->
write_sectors
+=
nr_sectors
;
if
(
!
new_io
)
rq
->
rq_disk
->
write_merges
++
;
}
if
(
new_io
)
{
disk_round_stats
(
rq
->
rq_disk
);
rq
->
rq_disk
->
in_flight
++
;
}
index
=
rq
->
rq_disk
->
first_minor
>>
rq
->
rq_disk
->
minor_shift
;
...
...
@@ -1454,6 +1460,33 @@ static inline void add_request(request_queue_t * q, struct request * req,
__elv_add_request_pos
(
q
,
req
,
insert_here
);
}
/*
* disk_round_stats() - Round off the performance stats on a struct
* disk_stats.
*
* The average IO queue length and utilisation statistics are maintained
* by observing the current state of the queue length and the amount of
* time it has been in this state for.
*
* Normally, that accounting is done on IO completion, but that can result
* in more than a second's worth of IO being accounted for within any one
* second, leading to >100% utilisation. To deal with that, we call this
* function to do a round-off before returning the results when reading
* /proc/diskstats. This accounts immediately for all queue usage up to
* the current jiffies and restarts the counters again.
*/
void
disk_round_stats
(
struct
gendisk
*
disk
)
{
unsigned
long
now
=
jiffies
;
disk
->
time_in_queue
+=
disk
->
in_flight
*
(
now
-
disk
->
stamp
);
disk
->
stamp
=
now
;
if
(
disk
->
in_flight
)
disk
->
io_ticks
+=
(
now
-
disk
->
stamp_idle
);
disk
->
stamp_idle
=
now
;
}
void
__blk_put_request
(
request_queue_t
*
q
,
struct
request
*
req
)
{
struct
request_list
*
rl
=
req
->
rl
;
...
...
@@ -1567,6 +1600,11 @@ static void attempt_merge(request_queue_t *q, struct request *req,
elv_merge_requests
(
q
,
req
,
next
);
if
(
req
->
rq_disk
)
{
disk_round_stats
(
req
->
rq_disk
);
req
->
rq_disk
->
in_flight
--
;
}
blkdev_dequeue_request
(
next
);
__blk_put_request
(
q
,
next
);
}
...
...
@@ -1758,6 +1796,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
req
->
bio
=
req
->
biotail
=
bio
;
req
->
rq_dev
=
to_kdev_t
(
bio
->
bi_bdev
->
bd_dev
);
req
->
rq_disk
=
bio
->
bi_bdev
->
bd_disk
;
req
->
start_time
=
jiffies
;
add_request
(
q
,
req
,
insert_here
);
out:
if
(
freereq
)
...
...
@@ -2096,9 +2135,25 @@ int end_that_request_chunk(struct request *req, int uptodate, int nr_bytes)
*/
void
end_that_request_last
(
struct
request
*
req
)
{
struct
gendisk
*
disk
=
req
->
rq_disk
;
if
(
req
->
waiting
)
complete
(
req
->
waiting
);
if
(
disk
)
{
unsigned
long
duration
=
jiffies
-
req
->
start_time
;
switch
(
rq_data_dir
(
req
))
{
case
WRITE
:
disk
->
writes
++
;
disk
->
write_ticks
+=
duration
;
break
;
case
READ
:
disk
->
reads
++
;
disk
->
read_ticks
+=
duration
;
break
;
}
disk_round_stats
(
disk
);
disk
->
in_flight
--
;
}
__blk_put_request
(
req
->
q
,
req
);
}
...
...
drivers/md/md.c
View file @
5ddfdaad
...
...
@@ -2768,7 +2768,7 @@ static int is_mddev_idle(mddev_t *mddev)
idle
=
1
;
ITERATE_RDEV
(
mddev
,
rdev
,
tmp
)
{
struct
gendisk
*
disk
=
rdev
->
bdev
->
bd_disk
;
curr_events
=
disk
->
read
s
+
disk
->
write
s
-
disk
->
sync_io
;
curr_events
=
disk
->
read
_sectors
+
disk
->
write_sector
s
-
disk
->
sync_io
;
if
((
curr_events
-
rdev
->
last_events
)
>
32
)
{
rdev
->
last_events
=
curr_events
;
idle
=
0
;
...
...
fs/partitions/check.c
View file @
5ddfdaad
...
...
@@ -302,9 +302,9 @@ static ssize_t part_stat_read(struct device *dev,
char
*
page
,
size_t
count
,
loff_t
off
)
{
struct
hd_struct
*
p
=
dev
->
driver_data
;
return
off
?
0
:
sprintf
(
page
,
"%
u %u %u %
u
\n
"
,
p
->
reads
,
p
->
read_sectors
,
p
->
writes
,
p
->
write_sectors
);
return
off
?
0
:
sprintf
(
page
,
"%
8u %8llu %8u %8ll
u
\n
"
,
p
->
reads
,
(
u64
)
p
->
read_sectors
,
p
->
writes
,
(
u64
)
p
->
write_sectors
);
}
static
struct
device_attribute
part_attr_dev
=
{
.
attr
=
{.
name
=
"dev"
,
.
mode
=
S_IRUGO
},
...
...
@@ -393,6 +393,27 @@ static ssize_t disk_size_read(struct device *dev,
struct
gendisk
*
disk
=
dev
->
driver_data
;
return
off
?
0
:
sprintf
(
page
,
"%llu
\n
"
,(
unsigned
long
long
)
get_capacity
(
disk
));
}
static
inline
unsigned
MSEC
(
unsigned
x
)
{
return
x
*
1000
/
HZ
;
}
static
ssize_t
disk_stat_read
(
struct
device
*
dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
struct
gendisk
*
disk
=
dev
->
driver_data
;
disk_round_stats
(
disk
);
return
off
?
0
:
sprintf
(
page
,
"%8u %8u %8llu %8u "
"%8u %8u %8llu %8u "
"%8u %8u %8u"
"
\n
"
,
disk
->
reads
,
disk
->
read_merges
,
(
u64
)
disk
->
read_sectors
,
MSEC
(
disk
->
read_ticks
),
disk
->
writes
,
disk
->
write_merges
,
(
u64
)
disk
->
write_sectors
,
MSEC
(
disk
->
write_ticks
),
disk
->
in_flight
,
MSEC
(
disk
->
io_ticks
),
MSEC
(
disk
->
time_in_queue
));
}
static
struct
device_attribute
disk_attr_dev
=
{
.
attr
=
{.
name
=
"dev"
,
.
mode
=
S_IRUGO
},
.
show
=
disk_dev_read
...
...
@@ -405,6 +426,10 @@ static struct device_attribute disk_attr_size = {
.
attr
=
{.
name
=
"size"
,
.
mode
=
S_IRUGO
},
.
show
=
disk_size_read
};
static
struct
device_attribute
disk_attr_stat
=
{
.
attr
=
{.
name
=
"stat"
,
.
mode
=
S_IRUGO
},
.
show
=
disk_stat_read
};
static
void
disk_driverfs_symlinks
(
struct
gendisk
*
disk
)
{
...
...
@@ -475,6 +500,7 @@ void register_disk(struct gendisk *disk)
device_create_file
(
dev
,
&
disk_attr_dev
);
device_create_file
(
dev
,
&
disk_attr_range
);
device_create_file
(
dev
,
&
disk_attr_size
);
device_create_file
(
dev
,
&
disk_attr_stat
);
disk_driverfs_symlinks
(
disk
);
if
(
disk
->
flags
&
GENHD_FL_CD
)
...
...
@@ -585,10 +611,19 @@ void del_gendisk(struct gendisk *disk)
disk
->
capacity
=
0
;
disk
->
flags
&=
~
GENHD_FL_UP
;
unlink_gendisk
(
disk
);
disk
->
reads
=
disk
->
writes
=
0
;
disk
->
read_sectors
=
disk
->
write_sectors
=
0
;
disk
->
read_merges
=
disk
->
write_merges
=
0
;
disk
->
read_ticks
=
disk
->
write_ticks
=
0
;
disk
->
in_flight
=
0
;
disk
->
io_ticks
=
0
;
disk
->
time_in_queue
=
0
;
disk
->
stamp
=
disk
->
stamp_idle
=
0
;
devfs_remove_partitions
(
disk
);
device_remove_file
(
&
disk
->
disk_dev
,
&
disk_attr_dev
);
device_remove_file
(
&
disk
->
disk_dev
,
&
disk_attr_range
);
device_remove_file
(
&
disk
->
disk_dev
,
&
disk_attr_size
);
device_remove_file
(
&
disk
->
disk_dev
,
&
disk_attr_stat
);
driverfs_remove_file
(
&
disk
->
disk_dev
.
dir
,
"device"
);
if
(
disk
->
driverfs_dev
)
{
driverfs_remove_file
(
&
disk
->
driverfs_dev
->
dir
,
"block"
);
...
...
include/linux/blkdev.h
View file @
5ddfdaad
...
...
@@ -39,6 +39,7 @@ struct request {
struct
gendisk
*
rq_disk
;
int
errors
;
sector_t
sector
;
unsigned
long
start_time
;
unsigned
long
nr_sectors
;
sector_t
hard_sector
;
/* the hard_* are block layer
* internals, no driver should
...
...
include/linux/genhd.h
View file @
5ddfdaad
...
...
@@ -99,10 +99,19 @@ struct gendisk {
int
policy
;
unsigned
sync_io
;
/* RAID */
unsigned
read_sectors
,
write_sectors
;
unsigned
reads
,
writes
;
unsigned
rio
,
wio
;
unsigned
read_merges
,
write_merges
;
unsigned
read_ticks
,
write_ticks
;
unsigned
io_ticks
;
int
in_flight
;
unsigned
long
stamp
,
stamp_idle
;
unsigned
time_in_queue
;
};
/* drivers/block/ll_rw_blk.c */
extern
void
disk_round_stats
(
struct
gendisk
*
disk
);
/* drivers/block/genhd.c */
extern
void
add_disk
(
struct
gendisk
*
disk
);
extern
void
del_gendisk
(
struct
gendisk
*
gp
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment