一 guest
1.1 直接方式 hcall
1.2 lazy方式
async_hcall
最多可以batch LHCALL_RING_SIZE个hypercalls.
在合适的时机选择lazy_mode, 进入async_hcall处理方式.
具体应用见arch_enter_lazy_mmu_mode
等函数
见下面的注释
/*G:035 Notice the lazy_hcall() above, rather than
hcall(). This is our first
* real optimization trick!
*
*
When lazy_mode is set, it means we're allowed to defer all hypercalls
and do
* them as a batch when lazy_mode is eventually turned off.
Because hypercalls
* are reasonably expensive, batching them up
makes sense. For example, a
* large mmap might update dozens of
page table entries: that code calls
*
lguest_lazy_mode(PARAVIRT_LAZY_MMU), does the dozen updates, then calls
*
lguest_lazy_mode(PARAVIRT_LAZY_NONE).
*
* So, when we're in
lazy mode, we call async_hypercall() to store the call for
* future
processing. When lazy mode is turned off we issue a hypercall to
*
flush the stored calls.
*
* There's also a hack where "mode" is
set to "PARAVIRT_LAZY_FLUSH" which
* indicates we're to flush any
outstanding calls immediately. This is used
* when an interrupt
handler does a kmap_atomic(): the page table changes must
* happen
immediately even if we're in the middle of a batch. Usually we're
*
not, though, so there's nothing to do. */
static enum
paravirt_lazy_mode lazy_mode; /* Note: not SMP-safe! */
lguest_data
由guest 和host 共享, 所以guest累积async hcall时不需要切换到host
struct lguest_data
{
/* 0xFF == done (set by Host), 0 == pending (set by Guest). */
u8 hcall_status[LHCALL_RING_SIZE];
/* The actual registers for
the hypercalls. */
struct hcall_ring hcalls[LHCALL_RING_SIZE];
};
1.3
xen 很早就支持,称为multicall
二
HOST
见do_hypercalls
阅读(993) | 评论(0) | 转发(0) |