grant table 相关代码分析(基于linux2.6.32) 初始化与构建部分
来源:互联网 发布:iar编译51单片机怎么样 编辑:程序博客网 时间:2024/06/10 00:24
初始化部分:
static int __devinit gnttab_init(void)
{
int i;
unsigned int max_nr_glist_frames, nr_glist_frames;
unsigned int nr_init_grefs;
if (!xen_domain()) 判断是否为xen的domain(直接忽略掉)
return -ENODEV;
nr_grant_frames = 1;
boot_max_nr_grant_frames = __max_nr_grant_frames(); //得到xen中定义的grant页框数,4.1中定义为32
/* Determine the maximum number of frames required for the
* grant reference free list on the current hypervisor.
*/
max_nr_glist_frames = (boot_max_nr_grant_frames *
GREFS_PER_GRANT_FRAME / RPP); //RPP是每页能装载的 grant_ref_t(uint32_t)数, GREFS_PER_GRANT_FRAME是每页装载的grant_entry数(大概64位),那么这应该等于16
gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *),
GFP_KERNEL); //为granttable分配足够空间, 16 * 4
if (gnttab_list == NULL)
return -ENOMEM;
nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP; //应该是granttable的个数,一共2页
for (i = 0; i < nr_glist_frames; i++) {
gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL);//每一项分配一页物理内存
if (gnttab_list[i] == NULL)
goto ini_nomem;
}
if (gnttab_resume() < 0)
return -ENODEV;
nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; //64项
for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++)
gnttab_entry(i) = i + 1;
gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END;
gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES;
gnttab_free_head = NR_RESERVED_ENTRIES;
//构建好了gnttab_list应该是2行32列,每行前8列不用,那么应该剩48项
printk("Grant table initialized\n");
return 0;
ini_nomem:
for (i--; i >= 0; i--)
free_page((unsigned long)gnttab_list[i]);
kfree(gnttab_list);
return -ENOMEM;
}
常用接口部分:
//将共享信息写入grant table中
static void update_grant_entry(grant_ref_t ref, domid_t domid,
unsigned long frame, unsigned flags)
{
/*
* Introducing a valid entry into the grant table:
* 1. Write ent->domid.
* 2. Write ent->frame:
* GTF_permit_access: Frame to which access is permitted.
* GTF_accept_transfer: Pseudo-phys frame slot being filled by new
* frame, or zero if none.
* 3. Write memory barrier (WMB).
* 4. Write ent->flags, inc. valid type.
*/
shared[ref].frame = frame;
shared[ref].domid = domid;
wmb();
shared[ref].flags = flags;
}
void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
unsigned long frame, int readonly)
{
update_grant_entry(ref, domid, frame,
GTF_permit_access | (readonly ? GTF_readonly : 0)); // GTF_permit_access表示允许domid映射或访问该frame
}
EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref);
int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
int readonly)
{
int ref;
ref = get_free_entries(1);//先得到一空项
if (unlikely(ref < 0))
return -ENOSPC;
gnttab_grant_foreign_access_ref(ref, domid, frame, readonly);
return ref;
}
结束访问部分:
static void do_free_callbacks(void)
{
struct gnttab_free_callback *callback, *next;
callback = gnttab_free_callback_list;
gnttab_free_callback_list = NULL;
while (callback != NULL) {
next = callback->next;
if (gnttab_free_count >= callback->count) {
callback->next = NULL;
callback->fn(callback->arg);
} else {
callback->next = gnttab_free_callback_list;
gnttab_free_callback_list = callback;
}
callback = next;
}
}
static inline void check_free_callbacks(void)
{
if (unlikely(gnttab_free_callback_list))
do_free_callbacks();
}
static void put_free_entry(grant_ref_t ref)//回收ref
{
unsigned long flags;
spin_lock_irqsave(&gnttab_list_lock, flags);
gnttab_entry(ref) = gnttab_free_head;
gnttab_free_head = ref;
gnttab_free_count++;
check_free_callbacks();
spin_unlock_irqrestore(&gnttab_list_lock, flags);
}
int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly)
{
u16 flags, nflags;
nflags = shared[ref].flags;
do {
flags = nflags;
if (flags & (GTF_reading|GTF_writing)) {
printk(KERN_ALERT "WARNING: g.e. still in use!\n");
return 0;
}
} while ((nflags = sync_cmpxchg(&shared[ref].flags, flags, 0)) != flags);// 判断是否正在使用,如果正在使用就不能删除
return 1;
}
EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref);
void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
unsigned long page)
{
if (gnttab_end_foreign_access_ref(ref, readonly)) {
put_free_entry(ref);//回收该ref(即对应的项)
if (page != 0)
free_page(page);
} else {
/* XXX This needs to be fixed so that the ref and page are
placed on a list to be freed up later. */
printk(KERN_WARNING
"WARNING: leaking g.e. and page still in use!\n");
}
}
- grant table 相关代码分析(基于linux2.6.32) 初始化与构建部分
- xen grant table机制分析
- 基于ARM处理器的linux中断详解(结合linux2.6.32.2-GQ2440分析)
- 基于Linux2.6.32内核对DMA架构分析
- Spring代码分析一:加载与初始化
- Spring代码分析:加载与初始化
- Spring代码分析一:加载与初始化
- Linux2.6.32内核笔记(4)内核链表使用与分析
- Mysql --skip-grant-table
- linux2.4 启动代码head.S分析
- linux2.6.xx内核代码分析
- linux2.6.xx内核代码分析
- linux2.4 启动代码head.S分析
- ArrayList部分源码分析(基于1.8)
- linphone源码分析----初始化部分
- linphone源码分析----初始化部分
- linphone源码分析----初始化部分
- 数据链表的相关代码与分析
- ext2文件系统
- Android 说说EditText里面的属性
- 如何对Intel IPP库进行静态链接
- ftp访问返回的各种数字码-意义
- 数组和集合的整理
- grant table 相关代码分析(基于linux2.6.32) 初始化与构建部分
- IP, UDP, RTP包头及MTU
- L二
- 串行异步通信-UART
- Android开发——MediaProvider源码分析(2)
- 那时,我们正年轻
- VS2010下安装boost库
- Linux系统下USB摄像头驱动开发
- Flash builder4 插件版破解