mirror of
https://github.com/versity/scoutfs.git
synced 2026-08-27 19:36:52 +00:00
Iterating over items backwards would result in a lot of extra work. When an item isn't present in the cache we go and search the segments for the item. Once we find the item in its stack of segments we also read in and cache all the items from the missing item to the end of all the segments. This reduced complexity a bit but had very bad worst case performance. If you read items backwards you constantly get cache misses that each search the segments for the item and then try to cache everything to the end of the segment. You're essentially working uncached and are doing quite a lot of work to get that single missed item cached each time. This adds the complexity to cache all the items in the segment stack around the missed item, not just after the missed item. Now reverse iteration hits cached items for everything in the segment after the initial miss. To make this work we have to pass the full lock coverage range to the item reading path. Then we search the manifest for segments that contain the missing key and use those segment's ranges to determine the full range of items that we'll cache. Then we again search the manifest for all the level 0 segments that intersect that range. That range extension is only for cached reads, it doesn't apply to the 'next' call which ignores caching. That operation is getting different enough that we pull it out into its own function. Signed-off-by: Zach Brown <zab@versity.com>
124 lines
4.1 KiB
C
124 lines
4.1 KiB
C
#ifndef _SCOUTFS_COUNTERS_H_
|
|
#define _SCOUTFS_COUNTERS_H_
|
|
|
|
#include <linux/kobject.h>
|
|
#include <linux/completion.h>
|
|
#include <linux/percpu_counter.h>
|
|
|
|
#include "super.h"
|
|
|
|
/*
|
|
* We only have to define each counter here and it'll be enumerated in
|
|
* other places by this macro. Don't forget to update LAST_COUNTER.
|
|
*/
|
|
#define EXPAND_EACH_COUNTER \
|
|
EXPAND_COUNTER(alloc_alloc) \
|
|
EXPAND_COUNTER(alloc_free) \
|
|
EXPAND_COUNTER(btree_stale_read) \
|
|
EXPAND_COUNTER(compact_operations) \
|
|
EXPAND_COUNTER(compact_segment_moved) \
|
|
EXPAND_COUNTER(compact_segment_read) \
|
|
EXPAND_COUNTER(compact_segment_write_bytes) \
|
|
EXPAND_COUNTER(compact_segment_writes) \
|
|
EXPAND_COUNTER(compact_stale_error) \
|
|
EXPAND_COUNTER(compact_sticky_upper) \
|
|
EXPAND_COUNTER(compact_sticky_written) \
|
|
EXPAND_COUNTER(data_end_writeback_page) \
|
|
EXPAND_COUNTER(data_invalidatepage) \
|
|
EXPAND_COUNTER(data_readpage) \
|
|
EXPAND_COUNTER(data_write_begin) \
|
|
EXPAND_COUNTER(data_write_end) \
|
|
EXPAND_COUNTER(data_writepage) \
|
|
EXPAND_COUNTER(dentry_revalidate_error) \
|
|
EXPAND_COUNTER(dentry_revalidate_invalid) \
|
|
EXPAND_COUNTER(dentry_revalidate_locked) \
|
|
EXPAND_COUNTER(dentry_revalidate_orphan) \
|
|
EXPAND_COUNTER(dentry_revalidate_rcu) \
|
|
EXPAND_COUNTER(dentry_revalidate_root) \
|
|
EXPAND_COUNTER(dentry_revalidate_valid) \
|
|
EXPAND_COUNTER(item_alloc) \
|
|
EXPAND_COUNTER(item_batch_duplicate) \
|
|
EXPAND_COUNTER(item_batch_inserted) \
|
|
EXPAND_COUNTER(item_create) \
|
|
EXPAND_COUNTER(item_delete) \
|
|
EXPAND_COUNTER(item_free) \
|
|
EXPAND_COUNTER(item_lookup_hit) \
|
|
EXPAND_COUNTER(item_lookup_miss) \
|
|
EXPAND_COUNTER(item_range_alloc) \
|
|
EXPAND_COUNTER(item_range_free) \
|
|
EXPAND_COUNTER(item_range_hit) \
|
|
EXPAND_COUNTER(item_range_insert) \
|
|
EXPAND_COUNTER(item_range_miss) \
|
|
EXPAND_COUNTER(item_shrink) \
|
|
EXPAND_COUNTER(item_shrink_alone) \
|
|
EXPAND_COUNTER(item_shrink_empty_range) \
|
|
EXPAND_COUNTER(item_shrink_next_dirty) \
|
|
EXPAND_COUNTER(item_shrink_outside) \
|
|
EXPAND_COUNTER(item_shrink_range_end) \
|
|
EXPAND_COUNTER(item_shrink_small_split) \
|
|
EXPAND_COUNTER(item_shrink_split_range) \
|
|
EXPAND_COUNTER(lock_alloc) \
|
|
EXPAND_COUNTER(lock_ast) \
|
|
EXPAND_COUNTER(lock_ast_edeadlk) \
|
|
EXPAND_COUNTER(lock_ast_error) \
|
|
EXPAND_COUNTER(lock_bast) \
|
|
EXPAND_COUNTER(lock_dlm_call) \
|
|
EXPAND_COUNTER(lock_dlm_call_error) \
|
|
EXPAND_COUNTER(lock_free) \
|
|
EXPAND_COUNTER(lock_grace_enforced) \
|
|
EXPAND_COUNTER(lock_grace_expired) \
|
|
EXPAND_COUNTER(lock_grace_extended) \
|
|
EXPAND_COUNTER(lock_invalidate_clean_item) \
|
|
EXPAND_COUNTER(lock_lock) \
|
|
EXPAND_COUNTER(lock_lock_error) \
|
|
EXPAND_COUNTER(lock_nonblock_eagain) \
|
|
EXPAND_COUNTER(lock_shrink) \
|
|
EXPAND_COUNTER(lock_write_dirty_item) \
|
|
EXPAND_COUNTER(lock_unlock) \
|
|
EXPAND_COUNTER(manifest_compact_migrate) \
|
|
EXPAND_COUNTER(manifest_hard_stale_error) \
|
|
EXPAND_COUNTER(manifest_read_excluded_key) \
|
|
EXPAND_COUNTER(seg_alloc) \
|
|
EXPAND_COUNTER(seg_free) \
|
|
EXPAND_COUNTER(seg_shrink) \
|
|
EXPAND_COUNTER(seg_stale_read) \
|
|
EXPAND_COUNTER(trans_commit_fsync) \
|
|
EXPAND_COUNTER(trans_commit_full) \
|
|
EXPAND_COUNTER(trans_commit_item_flush) \
|
|
EXPAND_COUNTER(trans_commit_sync_fs) \
|
|
EXPAND_COUNTER(trans_commit_timer) \
|
|
EXPAND_COUNTER(trans_level0_seg_write_bytes) \
|
|
EXPAND_COUNTER(trans_level0_seg_writes)
|
|
|
|
|
|
#define FIRST_COUNTER alloc_alloc
|
|
#define LAST_COUNTER trans_level0_seg_writes
|
|
|
|
#undef EXPAND_COUNTER
|
|
#define EXPAND_COUNTER(which) struct percpu_counter which;
|
|
|
|
struct scoutfs_counters {
|
|
/* $sysfs/fs/scoutfs/$id/counters/ */
|
|
struct kobject kobj;
|
|
struct completion comp;
|
|
|
|
EXPAND_EACH_COUNTER
|
|
};
|
|
|
|
#define scoutfs_foreach_counter(sb, pcpu) \
|
|
for (pcpu = &SCOUTFS_SB(sb)->counters->FIRST_COUNTER; \
|
|
pcpu <= &SCOUTFS_SB(sb)->counters->LAST_COUNTER; \
|
|
pcpu++)
|
|
|
|
#define scoutfs_inc_counter(sb, which) \
|
|
percpu_counter_inc(&SCOUTFS_SB(sb)->counters->which)
|
|
|
|
#define scoutfs_add_counter(sb, which, cnt) \
|
|
percpu_counter_add(&SCOUTFS_SB(sb)->counters->which, cnt)
|
|
|
|
void __init scoutfs_init_counters(void);
|
|
int scoutfs_setup_counters(struct super_block *sb);
|
|
void scoutfs_destroy_counters(struct super_block *sb);
|
|
|
|
#endif
|