Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104229
  • 博文数量: 17
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 241
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-06 13:16
个人简介

- -

文章分类

全部博文(17)

文章存档

2014年(9)

2013年(7)

2012年(1)

我的朋友

分类: 其他平台

2014-04-14 23:43:34



src/flashcache_main.c,
主入口,
EXPORT_SYMBOL() 注册了很多外部接口, 但都是在内部调用, 只是为了作为回调所以注册?


flashcache_ctr()
src/flashcache.h,
struct cache_c, cache context,
dmc 核心数据结构, 维护target, queue, 和其他count

dmc->num_sets = dmc->size >> dmc->assoc_shift
dmc->cache_sets[dmc->num_sets]
dmc->cache[]


#define DEFAULT_CACHE_ASSOC 512
#define DEFAULT_MD_BLOCK_SIZE 8 /* 4 KB */


struct cache_set, 2层LRU, warm + hot


struct cacheblock
u_int16_t lru_prev, lru_next,
u_int16_t hash_buckets[512], 环形队列


dmc->cache_mode, 构造时从参数中获取,
FLASHCACHE_WRITE_BACK
FLASHCACHE_WRITE_THROUGH
FLASHCACHE_WRITE_AROUND

dmc->cache, 根据dmc->cache_mode, 由
flashcache_writeback_create()/flashcache_writethrough_create()之类的函数分配,
dmc->cache = (struct cacheblock *)vmalloc(order)




flashcache_conf.c,
flashcache_init() =>
flashcache_target, 注册到dm的target, ctr/dtr/map/ioctl等
ctr() => flashcache_ctr()

=>
flashcache_reclaim_init_lru_lists()
LRU布局
-- LRU_HOT | LRU_WARM --
需要为每个dmc->cache_sets[set] 分配
两段式的LRU, nothing new ...




Add/del pids whose IOs should be non-cacheable.
flashcache_ioctl()
参考 src/flashcache_ioctl.h

NCPID_CMD => BLACKLIST
WHITELIST_CMD => WHITELIST
估计是先有了black list, 再发明了white list

dmc->blacklist_head, blacklist_tail
dmc->whitelist_head, whitelist_tail

就是对应的pid 是否执行cache, 大概吧



drivers/md/dm.c,
__map_bio()
将对设备bio转换成tio, 分发到各个dm_target上去
ti->type->map(struct dm_target * ti, clone_bio)
=>
flashcache_map()

read()/ write()

async() =>
flashcache_io_callback()
基本都是生成job, push到对应的job list中,



flashcache_init(), flashcache_conf.c,
INIT_WORK(&_kcached_wq, do_work);
由work_queue, 调用

do_work(), flashcache_subr.c
对5个job list,
LIST_HEAD(_pending_jobs);
LIST_HEAD(_io_jobs); LIST_HEAD(_md_io_jobs);
LIST_HEAD(_md_complete_jobs);
LIST_HEAD(_uncached_io_complete_jobs);
执行对应的处理函数



在flashcache_main.c中, **_callback()会调用
schedule_work(&_kcached_wq), 处理work_queue



为什么flashcache效率高?
1. 使用大块连续cache block, 维护cache和lru的都是cache内部的offset id,
而不是指针
不会产生太大影响

2. 多个job list, 不同的async操作在不同的list排队, 避免相互干扰
特别是区分了io和md_io(meta data)
flashcache_io_callback(), flashcache_main.c
区分方法:
1) READDISK -> push_io(), 只有readdisk用

2) WRITECACHE先执行写metadata,

flashcache_dirty_writeback() =>
flashcache_kcopyd_callback() =>
flashcache_md_write()

3) 写data丢给pending


jobs在flashcache_subr.c中实现, 其中是否有优先级实现 ???
该文件中应该没有, work_queue到哪里都一样

do_work() =>
process_jobs() 对5个jobs list, 每次只处理FLASHCACHE_YIELD = 32个,
一旦超过就yield(), 将会导致排在前面的jobs比后面的jobs有更多的执行机会,
从而实现优先级机制

排列顺序:
_md_complete_jobs
_pending_jobs
_md_io_jobs
_io_jobs
_uncached_io_complete_jobs

是否可以进一步优化 ???

很有趣, 很精彩, 这里才是效率提升的关键

3) flashcache_lookup(struct cache_c *dmc, struct bio *bio, int *index)
通过dmc和bio在连续内存dmc->cache[]中查找index
还是靠hash获取index
用数组或tree实现index定位, 效率上应该相差不大


flashcache_write()
在执行flashcache_lookup()后, 再检查cacheblk->dbn == bio->bi_sector,
避免hash冲突导致index误命中

flashcache_write_miss()
在发现hash冲突后, 必须先将原有的冲突hash和block清洗掉
flashcache_hash_remove()
能否重用冲突hash, 例如list ?


4) flashcache分区格式对性能的帮助
src/utils/flashcache_create.c,
最终调用dmsteup命令 =>
flashcache_ctr(), src/flashcache_conf.c


atomic_set(&dmc->hot_list_pct, FLASHCACHE_LRU_HOT_PCT_DEFAULT);
其中, FLASHCACHE_LRU_HOT_PCT_DEFAULT = 50
flashcache_reclaim_rebalance_lru(dmc, dmc->sysctl_lru_hot_pct),
flashcache_procfs.c

dmc->sysctl_lru_hot_pct = 75;
hot_blocks_set = (dmc->assoc * atomic_read(&dmc->hot_list_pct)) / 100
flashcache_reclaim.c

注意细节
flashcache_reclaim_rebalance_lru(),
使得warm list与hot list之间block数量在偏向dmc->sysctl_lru_hot_pct的比例变动,
即由50%向75%变化







阅读(2508) | 评论(0) | 转发(0) |
0

上一篇:doxygen graphviz

下一篇:fio 笔记

给主人留下些什么吧!~~