fix diskstats_show() accounting with PREEMPT
PATCH 1/1 fix diskstats_show() accounting with PREEMPT
there is another (minor) bug that the smp_processor_id() debugger
unearthed: diskstats_show() could do a disk_round_stats() -> disk_stat_add() with preemption enabled - possibly resulting in losing statistics updates.
Patch attached. (The overwhelming majority of disk_stat_add() callers have preemption disabled so fixing the remaining two was the best.)
Ingo
drivers/block/genhd.c renamed from drivers/block/genhd.c.orig +4 -0
@@ -365,7 +365,9 @@ static ssize_t disk_size_read(struct genstatic ssize_t disk_stats_read (struct gendisk * disk,char *page) { +preempt_disable ();disk_round_stats (disk); +preempt_enable ();return sprintf (page,"%8u %8u %8llu %8u " "%8u %8u %8llu %8u "
@@ -494,7 +496,9 @@ static int diskstats_show(struct seq_fil"\n\n"); */ +preempt_disable ();disk_round_stats (gp); +preempt_enable (); seq_printf(s, "%4d %4d %s %u %u %llu %u %u %u %llu %u %u %u %u\n", gp->major, n + gp->first_minor, disk_name(gp, n, buf), disk_stat_read(gp, reads), disk_stat_read(gp, read_merges),
Quoted 26 lines · Ingo Molnar
there is another (minor) bug that the
smp_processor_id()debugger
unearthed:diskstats_show()could do adisk_round_stats()->disk_stat_add()with preemption enabled - possibly resulting in losing statistics updates.Patch attached. (The overwhelming majority of
disk_stat_add()callers have preemption disabled so fixing the remaining two was the best.)Ingo
Signed-off-by Ingo Molnar <[email protected]>drivers/block/genhd.c renamed from drivers/block/genhd.c.orig +2
-0@@ -365,7 +365,9 @@ static ssize_t disk_size_read(struct genstatic ssize_t disk_stats_read (struct gendisk * disk,char *page) { +preempt_disable ();disk_round_stats (disk); +preempt_enable ();return sprintf (page,"%8u %8u %8llu %8u " "%8u %8u %8llu %8u "
drivers/block/genhd.c static int diskstats_show(struct seq_fil · line 504
Quoted 9 lines
drivers/block/genhd.c renamed from drivers/block/genhd.c.orig +2
-0@@ -494,7 +496,9 @@ static int diskstats_show(struct seq_fil"\n\n"); */ +preempt_disable ();disk_round_stats (gp); +preempt_enable (); seq_printf(s, "%4d %4d %s %u %u %llu %u %u %u %llu %u %u %u %u\n", gp->major, n + gp->first_minor, disk_name(gp, n, buf), disk_stat_read(gp, reads), disk_stat_read(gp, read_merges),
Looks fine, thanks Ingo.
Signature · 1 line
Jens Axboe