summaryrefslogtreecommitdiff
path: root/drivers/md/dm-stats.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-stats.c')
-rw-r--r--drivers/md/dm-stats.c13
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;