From 2fa7b537498a855953acc5765261914cf834c3ea Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Mon, 5 Aug 2013 12:26:57 -0400 Subject: [PATCH 5/8] dm cache: add @stats_clear message factored out reuseable code to share between print and clear --- drivers/md/dm-stats.c | 72 ++++++++++++++++++++++++++++++++++++------------ 1 files changed, 54 insertions(+), 18 deletions(-) diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c index 084fee3..3079555 100644 --- a/drivers/md/dm-stats.c +++ b/drivers/md/dm-stats.c @@ -343,6 +343,41 @@ void dm_stats_bio(struct dm_stats *st, rcu_read_unlock(); } +static void dm_stat_clear(struct dm_stat *stat) +{ + size_t x; + struct dm_stat_shared *s; + struct dm_stat_percpu *p; + + for (x = 0; x < stat->n_entries; x++) { + s = &stat->stat_shared[x]; + local_irq_disable(); + p = &stat->stat_percpu[smp_processor_id()][x]; + p->sectors[0] -= s->tmp.sectors[0]; + p->sectors[1] -= s->tmp.sectors[1]; + p->ios[0] -= s->tmp.ios[0]; + p->ios[1] -= s->tmp.ios[1]; + p->ticks[0] -= s->tmp.ticks[0]; + p->ticks[1] -= s->tmp.ticks[1]; + p->io_ticks -= s->tmp.io_ticks; + p->time_in_queue -= s->tmp.time_in_queue; + local_irq_enable(); + } +} + +static int dm_stats_clear(struct dm_stats *stats, int id) +{ + struct dm_stat *stat; + + stat = dm_stats_find(stats, id); + if (!stat) + return -ENOENT; + + dm_stat_clear(stat); + + return 1; +} + static int dm_stats_print(struct dm_stats *st, int id, bool clear, char *result, unsigned maxlen) { @@ -403,23 +438,8 @@ static int dm_stats_print(struct dm_stats *st, int id, bool clear, goto buffer_overflow; } - if (clear) { - for (x = 0; x < m->n_entries; x++) { - struct dm_stat_shared *s = &m->stat_shared[x]; - struct dm_stat_percpu *p; - local_irq_disable(); - p = &m->stat_percpu[smp_processor_id()][x]; - p->sectors[0] -= s->tmp.sectors[0]; - p->sectors[1] -= s->tmp.sectors[1]; - p->ios[0] -= s->tmp.ios[0]; - p->ios[1] -= s->tmp.ios[1]; - p->ticks[0] -= s->tmp.ticks[0]; - p->ticks[1] -= s->tmp.ticks[1]; - p->io_ticks -= s->tmp.io_ticks; - p->time_in_queue -= s->tmp.time_in_queue; - local_irq_enable(); - } - } + if (clear) + dm_stat_clear(m); buffer_overflow: mutex_unlock(&st->mutex); @@ -495,6 +515,21 @@ static int message_stats_delete(struct mapped_device *md, return dm_stats_delete(dm_get_stats(md), id); } +static int message_stats_clear(struct mapped_device *md, + unsigned argc, char **argv) +{ + int id; + char dummy; + + if (argc != 2) + return -EINVAL; + + if (sscanf(argv[1], "%d%c", &id, &dummy) != 1 || id < 0) + return -EINVAL; + + return dm_stats_clear(dm_get_stats(md), id); +} + static int message_stats_print(struct mapped_device *md, unsigned argc, char **argv, bool clear, char *result, unsigned maxlen) @@ -525,9 +560,10 @@ int dm_stats_message(struct mapped_device *md, unsigned argc, char **argv, r = message_stats_create(md, argc, argv, result, maxlen); else if (!strcasecmp(argv[0], "@stats_delete")) r = message_stats_delete(md, argc, argv); + else if (!strcasecmp(argv[0], "@stats_clear")) + r = message_stats_clear(md, argc, argv); else if (!strcasecmp(argv[0], "@stats_print")) r = message_stats_print(md, argc, argv, false, result, maxlen); - /* FIXME: why not have @stats_print + @stats_clear ? */ else if (!strcasecmp(argv[0], "@stats_print_clear")) r = message_stats_print(md, argc, argv, true, result, maxlen); else -- 1.7.1