diff options
-rw-r--r-- | drivers/md/bcache/sysfs.c | 182 |
1 files changed, 107 insertions, 75 deletions
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 17ce4a0e11cb..f4b0721e0e6a 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -42,6 +42,7 @@ read_attribute(nbuckets); read_attribute(tree_depth); read_attribute(root_usage_percent); read_attribute(priority_stats); +read_attribute(reserve_stats); read_attribute(btree_cache_size); read_attribute(cache_available_percent); read_attribute(written); @@ -719,6 +720,107 @@ static struct attribute *bch_cache_set_internal_files[] = { }; KTYPE(bch_cache_set_internal); +static ssize_t show_priority_stats(struct cache *ca, char *buf) +{ + int cmp(const void *l, const void *r) + { return *((u16 *) r) - *((u16 *) l); } + + struct bucket *b; + size_t n = ca->sb.nbuckets, i; + size_t unused = 0, available = 0, dirty = 0, meta = 0; + u64 sum = 0; + /* Compute 31 quantiles */ + u16 q[31], *p, *cached; + ssize_t ret; + + cached = p = vmalloc(ca->sb.nbuckets * sizeof(u16)); + if (!p) + return -ENOMEM; + + mutex_lock(&ca->set->bucket_lock); + for_each_bucket(b, ca) { + if (!GC_SECTORS_USED(b)) + unused++; + if (GC_MARK(b) == GC_MARK_RECLAIMABLE) + available++; + if (GC_MARK(b) == GC_MARK_DIRTY) + dirty++; + if (GC_MARK(b) == GC_MARK_METADATA) + meta++; + } + + for (i = ca->sb.first_bucket; i < n; i++) + p[i] = ca->buckets[i].read_prio; + mutex_unlock(&ca->set->bucket_lock); + + sort(p, n, sizeof(u16), cmp, NULL); + + while (n && + !cached[n - 1]) + --n; + + unused = ca->sb.nbuckets - n; + + for (i = 0; i < n; i++) + sum += INITIAL_PRIO - cached[i]; + + if (n) + do_div(sum, n); + + for (i = 0; i < ARRAY_SIZE(q); i++) + q[i] = INITIAL_PRIO - cached[n * (i + 1) / + (ARRAY_SIZE(q) + 1)]; + + vfree(p); + + ret = scnprintf(buf, PAGE_SIZE, + "Unused: %zu%% (%zu)\n" + "Clean: %zu%% (%zu)\n" + "Dirty: %zu%% (%zu)\n" + "Metadata: %zu%% (%zu)\n" + "Average: %llu\n" + "Sectors per Q: %zu\n" + "Quantiles: [", + unused * 100 / (size_t) ca->sb.nbuckets, unused, + available * 100 / (size_t) ca->sb.nbuckets, available, + dirty * 100 / (size_t) ca->sb.nbuckets, dirty, + meta * 100 / (size_t) ca->sb.nbuckets, meta, sum, + n * ca->sb.bucket_size / (ARRAY_SIZE(q) + 1)); + + for (i = 0; i < ARRAY_SIZE(q); i++) + ret += scnprintf(buf + ret, PAGE_SIZE - ret, + "%u ", q[i]); + ret--; + + ret += scnprintf(buf + ret, PAGE_SIZE - ret, "]\n"); + + return ret; + +} + +static ssize_t show_reserve_stats(struct cache *ca, char *buf) +{ + enum alloc_reserve i; + ssize_t ret; + + mutex_lock(&ca->set->bucket_lock); + + ret = scnprintf(buf, PAGE_SIZE, + "free_inc:\t%zu\t%zu\n", + fifo_used(&ca->free_inc), + ca->free_inc.size); + + for (i = 0; i < RESERVE_NR; i++) + ret += scnprintf(buf + ret, PAGE_SIZE - ret, + "free[%u]:\t%zu\t%zu\n", i, + fifo_used(&ca->free[i]), + ca->free[i].size); + + mutex_unlock(&ca->set->bucket_lock); + + return ret; +} + SHOW(__bch_cache) { struct cache *ca = container_of(kobj, struct cache, kobj); @@ -746,81 +848,10 @@ SHOW(__bch_cache) sysfs_print(tier, CACHE_TIER(&ca->sb)); - if (attr == &sysfs_priority_stats) { - int cmp(const void *l, const void *r) - { return *((uint16_t *) r) - *((uint16_t *) l); } - - struct bucket *b; - size_t n = ca->sb.nbuckets, i; - size_t unused = 0, available = 0, dirty = 0, meta = 0; - uint64_t sum = 0; - /* Compute 31 quantiles */ - uint16_t q[31], *p, *cached; - ssize_t ret; - - cached = p = vmalloc(ca->sb.nbuckets * sizeof(uint16_t)); - if (!p) - return -ENOMEM; - - mutex_lock(&ca->set->bucket_lock); - for_each_bucket(b, ca) { - if (!GC_SECTORS_USED(b)) - unused++; - if (GC_MARK(b) == GC_MARK_RECLAIMABLE) - available++; - if (GC_MARK(b) == GC_MARK_DIRTY) - dirty++; - if (GC_MARK(b) == GC_MARK_METADATA) - meta++; - } - - for (i = ca->sb.first_bucket; i < n; i++) - p[i] = ca->buckets[i].read_prio; - mutex_unlock(&ca->set->bucket_lock); - - sort(p, n, sizeof(uint16_t), cmp, NULL); - - while (n && - !cached[n - 1]) - --n; - - unused = ca->sb.nbuckets - n; - - for (i = 0; i < n; i++) - sum += INITIAL_PRIO - cached[i]; - - if (n) - do_div(sum, n); - - for (i = 0; i < ARRAY_SIZE(q); i++) - q[i] = INITIAL_PRIO - cached[n * (i + 1) / - (ARRAY_SIZE(q) + 1)]; - - vfree(p); - - ret = scnprintf(buf, PAGE_SIZE, - "Unused: %zu%%\n" - "Clean: %zu%%\n" - "Dirty: %zu%%\n" - "Metadata: %zu%%\n" - "Average: %llu\n" - "Sectors per Q: %zu\n" - "Quantiles: [", - unused * 100 / (size_t) ca->sb.nbuckets, - available * 100 / (size_t) ca->sb.nbuckets, - dirty * 100 / (size_t) ca->sb.nbuckets, - meta * 100 / (size_t) ca->sb.nbuckets, sum, - n * ca->sb.bucket_size / (ARRAY_SIZE(q) + 1)); - - for (i = 0; i < ARRAY_SIZE(q); i++) - ret += scnprintf(buf + ret, PAGE_SIZE - ret, - "%u ", q[i]); - ret--; - - ret += scnprintf(buf + ret, PAGE_SIZE - ret, "]\n"); - - return ret; - } + if (attr == &sysfs_priority_stats) + return show_priority_stats(ca, buf); + if (attr == &sysfs_reserve_stats) + return show_reserve_stats(ca, buf); return 0; } @@ -912,6 +943,7 @@ static struct attribute *bch_cache_files[] = { &sysfs_block_size, &sysfs_nbuckets, &sysfs_priority_stats, + &sysfs_reserve_stats, &sysfs_discard, &sysfs_written, &sysfs_btree_written, |