mirror of
https://github.com/versity/scoutfs.git
synced 2026-09-20 06:54:28 +00:00
scoutfs: add some segment cache life cycle tracing
Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
+3
-1
@@ -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) \
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user