diff options
Diffstat (limited to 'drivers/md/dm-stats.c')
-rw-r--r-- | drivers/md/dm-stats.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c index b738f565bf5a..6de2104181b6 100644 --- a/drivers/md/dm-stats.c +++ b/drivers/md/dm-stats.c @@ -336,6 +336,7 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end, if (s->n_histogram_entries) { unsigned long long *hi; + hi = dm_kvzalloc(s->histogram_alloc_size, NUMA_NO_NODE); if (!hi) { r = -ENOMEM; @@ -357,6 +358,7 @@ static int dm_stats_create(struct dm_stats *stats, sector_t start, sector_t end, s->stat_percpu[cpu] = p; if (s->n_histogram_entries) { unsigned long long *hi; + hi = dm_kvzalloc(s->histogram_alloc_size, cpu_to_node(cpu)); if (!hi) { r = -ENOMEM; @@ -495,6 +497,7 @@ static int dm_stats_list(struct dm_stats *stats, const char *program, DMEMIT(" precise_timestamps"); if (s->n_histogram_entries) { unsigned int i; + DMEMIT(" histogram:"); for (i = 0; i < s->n_histogram_entries; i++) { if (i) @@ -567,6 +570,7 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry, */ #if BITS_PER_LONG == 32 unsigned long flags; + local_irq_save(flags); #else preempt_disable(); @@ -578,6 +582,7 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry, atomic_inc(&shared->in_flight[idx]); } else { unsigned long long duration; + dm_stat_round(s, shared, p); atomic_dec(&shared->in_flight[idx]); p->sectors[idx] += len; @@ -592,8 +597,10 @@ static void dm_stat_for_entry(struct dm_stat *s, size_t entry, } if (s->n_histogram_entries) { unsigned int lo = 0, hi = s->n_histogram_entries + 1; + while (lo + 1 < hi) { unsigned int mid = (lo + hi) / 2; + if (s->histogram_boundaries[mid - 1] > duration) { hi = mid; } else { @@ -741,6 +748,7 @@ static void __dm_stat_init_temporary_percpu_totals(struct dm_stat_shared *shared shared->tmp.time_in_queue += READ_ONCE(p->time_in_queue); if (s->n_histogram_entries) { unsigned int i; + for (i = 0; i < s->n_histogram_entries + 1; i++) shared->tmp.histogram[i] += READ_ONCE(p->histogram[i]); } @@ -775,6 +783,7 @@ static void __dm_stat_clear(struct dm_stat *s, size_t idx_start, size_t idx_end, local_irq_enable(); if (s->n_histogram_entries) { unsigned int i; + for (i = 0; i < s->n_histogram_entries + 1; i++) { local_irq_disable(); p = &s->stat_percpu[smp_processor_id()][x]; @@ -890,6 +899,7 @@ static int dm_stats_print(struct dm_stats *stats, int id, dm_jiffies_to_msec64(s, shared->tmp.io_ticks[WRITE])); if (s->n_histogram_entries) { unsigned int i; + for (i = 0; i < s->n_histogram_entries + 1; i++) { DMEMIT("%s%llu", !i ? " " : ":", shared->tmp.histogram[i]); } @@ -962,6 +972,7 @@ static int parse_histogram(const char *h, unsigned int *n_histogram_entries, unsigned long long hi; int s; char ch; + s = sscanf(h, "%llu%c", &hi, &ch); if (!s || (s == 2 && ch != ',')) return -EINVAL; @@ -987,10 +998,8 @@ static int message_stats_create(struct mapped_device *md, unsigned int divisor; const char *program_id, *aux_data; unsigned int stat_flags = 0; - unsigned int n_histogram_entries = 0; unsigned long long *histogram_boundaries = NULL; - struct dm_arg_set as, as_backup; const char *a; unsigned int feature_args; |