linux充气服务器,XenLinux balloon的实现分析

balloon的概念来自下面的经典论文

Carl Waldspurger. in Proceedings of the 5th

Symposium on Operating Systems Design and Implementation, 2002

简而言之,balloon就是VMM打入guest的一个探子,通常以驱动方式存在,当guest空闲内存比较多时,通过吹气球inflat,让balloon申请若干内存,然后转给VMM。当guest load比较重,可以放气deflat,让VMM塞给balloon若干内存,然后balloon释放给guest。Linux 3.0已经包含了balloon for Xen的实现。

OVERVIEW

balloon的状态由描述,该结构在balloon_init函数中初始化。

struct {

//in xen/balloon.h

/*

We aim for 'current allocation' == 'target allocation'. */

unsigned

long current_pages;//guest当前实际mfn数目

unsigned

long ;//balloon期待guest拥有的mfn数目

/*

Number of pages in high- and low-memory balloons. guest中被剥夺mfn的页面*/

unsigned

long balloon_low;

unsigned

long balloon_high;

unsigned

long schedule_delay;

unsigned

long max_schedule_delay;

unsigned

long retry_count;

unsigned

long max_retry_count;

};

工作队列负责具体的操作,实际处理函数balloon_process根据target_pages值决定充气还是放气。外围代码通过调用balloon_set_new_target驱动balloon_worker。

static DECLARE_DELAYED_WORK(, );

balloon的外围代码在linux 3.0/drivers/xen/xen-balloon.c中,一个是xenstore的节点memory/target设置watch,另一个是在guest的sysfs文件系统创建子目录xen_memory,该子目录下有几个文件读/写balloon_stats的状态

核心操作inflat和deflat

主要代码中

increase_reservation对应放气,增加guest的内存。

decrease_reservation对应吹气,减少guest的内存。

/* List of ,

threaded through the mem_map array. ballooned_pages的页面都是有struct page结构,但是其对应的mfn已经被xen回收了

*/

static LIST_HEAD();

static enum bp_state

increase_reservation(unsigned long nr_pages)

{

int

rc;

unsigned

longpfn, i;

struct

page*page;

struct

xen_memory_reservation reservation = {

.address_bits

= 0,

.extent_order

= 0,

.domid= DOMID_SELF

};

/*下面的先取得若干page结构,然后通过超级调用populate_physmap让xen给这些page分配mfn,但是实际并不是如此,返回的mfn放在列表中,但是并没有和开始传递进去的各个page绑定起来,也就是前面传进去的参数只有reservation.nr_extents = nr_pages;才有作用,page传进去似乎是浪费(只有XENMEMF_populate_on_demand标记传进去page才有作用 fix me)。

*/

page

= balloon_first_page();

for

(i = 0; i < nr_pages; i++) {

if

(!page) {

nr_pages

= i;

break;

}

frame_list[i]

= page_to_pfn(page);

page

= balloon_next_page(page);

}

set_xen_guest_handle(reservation.extent_start,

);

rc

= HYPERVISOR_memory_op(,

&reservation);

//将部分page从ballooned pages摘除,和frame_list中取得的mfn绑定,包括P2M表,

//,最后guest使用

for

(i = 0; i < rc; i++) {

page

= balloon_retrieve(false);

pfn

= page_to_pfn(page);

set_phys_to_machine(pfn,

);//更新P2M表

/*

Link back into the page tables if not highmem. */

if

(xen_pv_domain() && !PageHighMem(page)) {

int

ret;

ret

= HYPERVISOR_update_va_mapping(//更新guest的页表

(unsigned

long)__va(pfn << PAGE_SHIFT),

mfn_pte(frame_list[i],

PAGE_KERNEL),

0);

}

/*

Relinquish the page back to the allocator. */

ClearPageReserved(page);

init_page_count(page);

;//释放给guest使用

}

balloon_stats.current_pages

+= rc;

return

BP_DONE;

}

static enum bp_state

decrease_reservation(unsigned long nr_pages, gfp_t gfp)

{

enum

bp_state state = BP_DONE;

unsigned

longpfn, i;

struct

page*page;

int

ret;

struct

xen_memory_reservation reservation = {

.address_bits

= 0,

.extent_order

= 0,

.domid= DOMID_SELF

};

for

(i = 0; i < nr_pages; i++) {

if

((page = alloc_page(gfp)) == NULL) {//向guest申请页面

nr_pages

= i;

state

= BP_EAGAIN;

break;

}

pfn

= page_to_pfn(page);

frame_list[i]

= pfn_to_mfn(pfn);//取得对应的mfn

scrub_page(page);

//为安全起见(可以挪到另一个guest使用),清0

if

(xen_pv_domain() && !PageHighMem(page)) {

ret

= HYPERVISOR_update_va_mapping(//将页表项清0

(unsigned

long)__va(pfn << PAGE_SHIFT),

__pte_ma(0),

0);

}

}

/*

Ensure that ballooned highmem pages don't have kmaps. */

kmap_flush_unused();

flush_tlb_all();

/*

No more mappings: invalidate P2M

and add to balloon. */

for

(i = 0; i < nr_pages; i++) {

pfn

= mfn_to_pfn(frame_list[i]);

__set_phys_to_machine(pfn,

INVALID_P2M_ENTRY);

balloon_append(pfn_to_page(pfn));//将page加入ballooned_pages链表

}

set_xen_guest_handle(reservation.extent_start,

frame_list);

reservation.nr_extents= nr_pages;

//将mfn转给Xen

ret

= HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);

balloon_stats.current_pages

-= nr_pages;

return

state;

}

alloc_xenballooned_pages和free_xenballooned_pages接口

Pages that have been ballooned are useful

for other Xen drivers doing grant table actions, because these pages have valid

struct page/PFNs but have no valid MFN so are available for remapping.

Xen的支持

见do_memory_op中的XENMEM_increase_reservation和XENMEM_decrease_reservation。increase_reservation是利用alloc_domheap_pages从Xen中获取物理页面,而decrease_reservation是调用guest_remove_page从guest回收页面。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值