scoutfs: add some segment cache life cycle tracing

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2017-06-27 14:04:38 -07:00
parent 70c7178e6a
commit 823a5bed34
4 changed files with 69 additions and 17 deletions
+3 -1
View File
@@ -14,7 +14,9 @@
#define EXPAND_EACH_COUNTER \
EXPAND_COUNTER(alloc_alloc) \
EXPAND_COUNTER(alloc_free) \
EXPAND_COUNTER(seg_lru_shrink) \
EXPAND_COUNTER(seg_alloc) \
EXPAND_COUNTER(seg_shrink) \
EXPAND_COUNTER(seg_free) \
EXPAND_COUNTER(trans_level0_seg_write) \
EXPAND_COUNTER(manifest_compact_migrate) \
EXPAND_COUNTER(compact_operations) \
+42
View File
@@ -29,6 +29,7 @@
#include "format.h"
#include "kvec.h"
#include "lock.h"
#include "seg.h"
struct scoutfs_sb_info;
@@ -357,6 +358,47 @@ TRACE_EVENT(scoutfs_lock_invalidate_sb,
__get_str(start), __get_str(end))
);
DECLARE_EVENT_CLASS(scoutfs_seg_class,
TP_PROTO(struct scoutfs_segment *seg),
TP_ARGS(seg),
TP_STRUCT__entry(
__field(unsigned int, major)
__field(unsigned int, minor)
__field(struct scoutfs_segment *, seg)
__field(int, refcount)
__field(u64, segno)
__field(unsigned long, flags)
__field(int, err)
),
TP_fast_assign(
__entry->major = MAJOR(seg->sb->s_bdev->bd_dev);
__entry->minor = MINOR(seg->sb->s_bdev->bd_dev);
__entry->seg = seg;
__entry->refcount = atomic_read(&seg->refcount);
__entry->segno = seg->segno;
__entry->flags = seg->flags;
__entry->err = seg->err;
),
TP_printk("dev %u:%u seg %p refcount %d segno %llu flags %lx err %d",
__entry->major, __entry->minor, __entry->seg, __entry->refcount,
__entry->segno, __entry->flags, __entry->err)
);
DEFINE_EVENT(scoutfs_seg_class, scoutfs_seg_alloc,
TP_PROTO(struct scoutfs_segment *seg),
TP_ARGS(seg)
);
DEFINE_EVENT(scoutfs_seg_class, scoutfs_seg_shrink,
TP_PROTO(struct scoutfs_segment *seg),
TP_ARGS(seg)
);
DEFINE_EVENT(scoutfs_seg_class, scoutfs_seg_free,
TP_PROTO(struct scoutfs_segment *seg),
TP_ARGS(seg)
);
#endif /* _TRACE_SCOUTFS_H */
/* This part must be outside protection */
+12 -15
View File
@@ -26,6 +26,7 @@
#include "alloc.h"
#include "key.h"
#include "counters.h"
#include "scoutfs_trace.h"
/*
* seg.c should just be about the cache and io, and maybe
@@ -49,21 +50,12 @@ struct segment_cache {
unsigned long lru_nr;
};
struct scoutfs_segment {
struct rb_node node;
struct list_head lru_entry;
atomic_t refcount;
u64 segno;
unsigned long flags;
int err;
struct page *pages[SCOUTFS_SEGMENT_PAGES];
};
enum {
SF_END_IO = 0,
};
static struct scoutfs_segment *alloc_seg(u64 segno)
static struct scoutfs_segment *alloc_seg(struct super_block *sb, u64 segno)
{
struct scoutfs_segment *seg;
struct page *page;
@@ -76,6 +68,7 @@ static struct scoutfs_segment *alloc_seg(u64 segno)
if (!seg)
return seg;
seg->sb = sb;
RB_CLEAR_NODE(&seg->node);
INIT_LIST_HEAD(&seg->lru_entry);
atomic_set(&seg->refcount, 1);
@@ -83,8 +76,6 @@ static struct scoutfs_segment *alloc_seg(u64 segno)
for (i = 0; i < SCOUTFS_SEGMENT_PAGES; i++) {
page = alloc_page(GFP_NOFS);
trace_printk("seg %p segno %llu page %u %p\n",
seg, segno, i, page);
if (!page) {
scoutfs_seg_put(seg);
return ERR_PTR(-ENOMEM);
@@ -93,6 +84,9 @@ static struct scoutfs_segment *alloc_seg(u64 segno)
seg->pages[i] = page;
}
trace_scoutfs_seg_alloc(seg);
scoutfs_inc_counter(sb, seg_alloc);
return seg;
}
@@ -106,6 +100,8 @@ void scoutfs_seg_put(struct scoutfs_segment *seg)
int i;
if (!IS_ERR_OR_NULL(seg) && atomic_dec_and_test(&seg->refcount)) {
trace_scoutfs_seg_free(seg);
scoutfs_inc_counter(seg->sb, seg_free);
WARN_ON_ONCE(!RB_EMPTY_NODE(&seg->node));
WARN_ON_ONCE(!list_empty(&seg->lru_entry));
for (i = 0; i < SCOUTFS_SEGMENT_PAGES; i++)
@@ -256,7 +252,7 @@ int scoutfs_seg_alloc(struct super_block *sb, u64 segno,
unsigned long flags;
int ret;
seg = alloc_seg(segno);
seg = alloc_seg(sb, segno);
if (!seg) {
ret = -ENOMEM;
goto out;
@@ -321,7 +317,7 @@ struct scoutfs_segment *scoutfs_seg_submit_read(struct super_block *sb,
if (seg)
return seg;
seg = alloc_seg(segno);
seg = alloc_seg(sb, segno);
if (IS_ERR(seg))
return seg;
@@ -776,7 +772,8 @@ static int seg_lru_shrink(struct shrinker *shrink, struct shrink_control *sc)
spin_unlock_irqrestore(&cac->lock, flags);
list_for_each_entry_safe(seg, tmp, &list, lru_entry) {
scoutfs_inc_counter(sb, seg_lru_shrink);
trace_scoutfs_seg_shrink(seg);
scoutfs_inc_counter(sb, seg_shrink);
list_del_init(&seg->lru_entry);
scoutfs_seg_put(seg);
}
+12 -1
View File
@@ -2,10 +2,21 @@
#define _SCOUTFS_SEG_H_
struct scoutfs_bio_completion;
struct scoutfs_segment;
struct scoutfs_key_buf;
struct kvec;
/* this is only visible for trace events */
struct scoutfs_segment {
struct super_block *sb;
struct rb_node node;
struct list_head lru_entry;
atomic_t refcount;
u64 segno;
unsigned long flags;
int err;
struct page *pages[SCOUTFS_SEGMENT_PAGES];
};
struct scoutfs_segment *scoutfs_seg_submit_read(struct super_block *sb,
u64 segno);
int scoutfs_seg_wait(struct super_block *sb, struct scoutfs_segment *seg);