内存脏数据下刷(linux2.6.18/linux.2.6.32)剖析

本文详细剖析了Linux内核2.6.18和2.6.32中内存脏数据下刷的机制。2.6.18内核依赖pdflush线程,而2.6.32内核将下刷功能整合到backing_dev_info(BDI)机制,为每个设备创建单独的flush线程。对比两者在结构、初始化、下刷时机和流程上的差异,2.6.32内核的改进提高了下刷效率,但也可能导致磁盘抖动。
摘要由CSDN通过智能技术生成

BDI机制原本主要是用于检测磁盘的繁忙程度等作用,从2.6.19内核开始,将此部分功能整合到了mm/backing_dev.c中,一直到2.6.31内核为止,其功能也只是在不段的完善,但是脏数据的下刷依然是依靠pdflush。自2.6.32内核开始,彻底取消了pdflush,而是将此部分功能添加到BDI机制中,并且是为每个设备创建了一个名为“flush-设备主次设备号”的线程,用于脏数据的下刷。

2   结构backing_dev_info

了解BDI机制,首先得清楚结构backing_dev_info,其定义在描述设备的结构gendisk->request_queue内。

2.1 Kernel-2.6.18

在2.6.18内核中其定义如下:

struct backing_dev_info {

        unsigned long ra_pages; /* maxreadahead in PAGE_CACHE_SIZE units */

        unsigned long state;    /* Always use atomic bitops on this */

        unsigned int capabilities; /*Device capabilities */

        congested_fn *congested_fn; /*Function pointer if device is md/dm */

        void *congested_data;   /* Pointer to aux data for congested func */

        void (*unplug_io_fn)(structbacking_dev_info *, struct page *);

        void *unplug_io_data;

};

其对应的state状态有:

enum bdi_state {

        BDI_pdflush,            /* A pdflush thread is working thisdevice */

       BDI_write_congested,    /* Thewrite queue is getting full */

       BDI_read_congested,     /* Theread queue is getting full */

        BDI_unused,             /* Available bits start here */

};

其初始化在:

a)  函数blk_queue_make_request:初始化ra_pages、state、capabilities

b)  函数blk_alloc_queue_node:初始化unplug_io_fn、unplug_io_data

2.2 Kernel-2.6.32

在2.6.32内核中其定义如下:

struct backing_dev_info {

        struct list_head bdi_list;

        struct rcu_head rcu_head;

        unsigned long ra_pages; /* maxreadahead in PAGE_CACHE_SIZE units */

        unsigned long state;    /* Always use atomic bitops on this */

        unsigned int capabilities; /*Device capabilities */

        congested_fn *congested_fn; /* Functionpointer if device is md/dm */

        void *congested_data;   /* Pointer to aux data for congested func */

        void (*unplug_io_fn)(structbacking_dev_info *, struct page *);

        void *unplug_io_data;

        char *name;              /* device_name */

        struct percpu_counterbdi_stat[NR_BDI_STAT_ITEMS];

        struct prop_local_percpucompletions;

        int dirty_exceeded;

        unsigned int min_ratio;

        unsigned int max_ratio, max_prop_frac;

        struct bdi_writeback wb;  /* default writeback info for this bdi */

        spinlock_t wb_lock;       /* protects update side of wb_list */

        struct list_head wb_list; /* theflusher threads hanging off this bdi */

        struct list_head work_list;

        struct device *dev;

#ifdef CONFIG_DEBUG_FS

        struct dentry *debug_dir;

        struct dentry *debug_stats;

#endif

};

其对应的state状态有:

enum bdi_state {

        BDI_pending,            /* On its way to being activated */

        BDI_wb_alloc,           /* Default embedded wb allocated */

       BDI_async_congested,    /* Theasync (write) queue is getting full */

       BDI_sync_congested,     /* Thesync queue is getting full */

        BDI_registered,         /* bdi_register() was done */

        BDI_unused,             /* Available bits start here */

};

用于sys接口计数统计的数值:

enum bdi_stat_item {

        BDI_RECLAIMABLE,

        BDI_WRITEBACK,

        NR_BDI_STAT_ITEMS

};

其初始化在:

a)  函数blk_alloc_queue_node:初始化ra_pages、state、capabilities、unplug_io_fn、unplug_io_data、name

b)  函数blk_alloc_que

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值