Bundle vcpu_time and vcpu_info structures together into a single

structure that is 64 bytes on x86. This ensures that indexing into
the array is fast (power-of-two size) and that accesses are cache
friendly (cache line size is usually 32 or 64 bytes).

Rename vcpu_data to vcpu_info, vcpu_time to vcpu_info.time.

Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-11-28 19:48:54 +01:00
1 parent 491738a4be
commit 9bd97f28fa
24 files changed
+73 -72

No files matched your search

@@ -155,7 +155,7 @@ irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
unsigned int l1i, l2i, port;
irqreturn_t (*handler)(int, void *, struct pt_regs *);
shared_info_t *s = HYPERVISOR_shared_info;
vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()];
vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()];
vcpu_info->evtchn_upcall_mask = 1;
vcpu_info->evtchn_upcall_pending = 0;
@@ -203,7 +203,7 @@ int evtchn_irq = 0xe9;
void __init evtchn_init(void)
{
shared_info_t *s = HYPERVISOR_shared_info;
vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()];
vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()];
#if 0
int ret;
@@ -81,7 +81,7 @@ VM_MASK = 0x00020000
#define evtchn_upcall_pending /* 0 */
#define evtchn_upcall_mask 1
#define sizeof_vcpu_shift 4
#define sizeof_vcpu_shift 6
#ifdef CONFIG_SMP
#define preempt_disable(reg) incl TI_preempt_count(reg)
@@ -204,7 +204,8 @@ static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
void init_cpu_khz(void)
{
u64 __cpu_khz = 1000000ULL << 32;
struct vcpu_time_info *info = &HYPERVISOR_shared_info->vcpu_time[0];
struct vcpu_time_info *info;
info = &HYPERVISOR_shared_info->vcpu_info[0].time;
do_div(__cpu_khz, info->tsc_to_system_mul);
if ( info->tsc_shift < 0 )
cpu_khz = __cpu_khz << -info->tsc_shift;
@@ -284,7 +285,7 @@ static void get_time_values_from_xen(void)
struct vcpu_time_info *src;
struct shadow_time_info *dst;
src = &s->vcpu_time[smp_processor_id()];
src = &s->vcpu_info[smp_processor_id()].time;
dst = &per_cpu(shadow_time, smp_processor_id());
do {
@@ -306,7 +307,7 @@ static inline int time_values_up_to_date(int cpu)
struct vcpu_time_info *src;
struct shadow_time_info *dst;
src = &HYPERVISOR_shared_info->vcpu_time[cpu];
src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
dst = &per_cpu(shadow_time, cpu);
return (dst->version == src->version);
@@ -291,7 +291,7 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code)
int write;
siginfo_t info;
address = HYPERVISOR_shared_info->vcpu_data[
address = HYPERVISOR_shared_info->vcpu_info[
smp_processor_id()].arch.cr2;
/* Set the "privileged fault" bit to something sane. */
@@ -154,7 +154,7 @@ asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
unsigned int l1i, l2i, port;
int irq, cpu = smp_processor_id();
shared_info_t *s = HYPERVISOR_shared_info;
vcpu_info_t *vcpu_info = &s->vcpu_data[cpu];
vcpu_info_t *vcpu_info = &s->vcpu_info[cpu];
vcpu_info->evtchn_upcall_pending = 0;
@@ -5,7 +5,7 @@
#define evtchn_upcall_pending 0
#define evtchn_upcall_mask 1
#define sizeof_vcpu_shift 5
#define sizeof_vcpu_shift 6
#ifdef CONFIG_SMP
//#define preempt_disable(reg) incl threadinfo_preempt_count(reg)
@@ -344,7 +344,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
#endif
/* get the address */
address = HYPERVISOR_shared_info->vcpu_data[
address = HYPERVISOR_shared_info->vcpu_info[
smp_processor_id()].arch.cr2;
if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
@@ -501,7 +501,7 @@ __asm__ __volatile__("6667:movl %1, %0\n6668:\n" \
do { \
vcpu_info_t *_vcpu; \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
_vcpu->evtchn_upcall_mask = 1; \
preempt_enable_no_resched(); \
barrier(); \
@@ -512,7 +512,7 @@ do { \
vcpu_info_t *_vcpu; \
barrier(); \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
_vcpu->evtchn_upcall_mask = 0; \
barrier(); /* unmask then check (avoid races) */ \
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
@@ -524,7 +524,7 @@ do { \
do { \
vcpu_info_t *_vcpu; \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
(x) = _vcpu->evtchn_upcall_mask; \
preempt_enable(); \
} while (0)
@@ -534,7 +534,7 @@ do { \
vcpu_info_t *_vcpu; \
barrier(); \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
barrier(); /* unmask then check (avoid races) */ \
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
@@ -550,7 +550,7 @@ do { \
do { \
vcpu_info_t *_vcpu; \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
(x) = _vcpu->evtchn_upcall_mask; \
_vcpu->evtchn_upcall_mask = 1; \
preempt_enable_no_resched(); \
@@ -568,7 +568,7 @@ do { \
({ int ___x; \
vcpu_info_t *_vcpu; \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
___x = (_vcpu->evtchn_upcall_mask != 0); \
preempt_enable_no_resched(); \
___x; })
@@ -325,7 +325,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
do { \
vcpu_info_t *_vcpu; \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
_vcpu->evtchn_upcall_mask = 1; \
preempt_enable_no_resched(); \
barrier(); \
@@ -336,7 +336,7 @@ do { \
vcpu_info_t *_vcpu; \
barrier(); \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
_vcpu->evtchn_upcall_mask = 0; \
barrier(); /* unmask then check (avoid races) */ \
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
@@ -348,7 +348,7 @@ do { \
do { \
vcpu_info_t *_vcpu; \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
(x) = _vcpu->evtchn_upcall_mask; \
preempt_enable(); \
} while (0)
@@ -358,7 +358,7 @@ do { \
vcpu_info_t *_vcpu; \
barrier(); \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
barrier(); /* unmask then check (avoid races) */ \
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
@@ -374,7 +374,7 @@ do { \
do { \
vcpu_info_t *_vcpu; \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
(x) = _vcpu->evtchn_upcall_mask; \
_vcpu->evtchn_upcall_mask = 1; \
preempt_enable_no_resched(); \
@@ -394,7 +394,7 @@ void cpu_idle_wait(void);
({ int ___x; \
vcpu_info_t *_vcpu; \
preempt_disable(); \
_vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
___x = (_vcpu->evtchn_upcall_mask != 0); \
preempt_enable_no_resched(); \
___x; })
@@ -102,7 +102,7 @@ static inline void mask_evtchn(int port)
static inline void unmask_evtchn(int port)
{
shared_info_t *s = HYPERVISOR_shared_info;
vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()];
vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()];
synch_clear_bit(port, &s->evtchn_mask[0]);
+1 -1
View File
@@ -657,7 +657,7 @@ static int setup_guest(int xc_handle,
memset(shared_info, 0, sizeof(shared_info_t));
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
munmap(shared_info, PAGE_SIZE);
+1 -1
View File
@@ -671,7 +671,7 @@ int xc_linux_restore(int xc_handle, int io_fd,
memset(&(shared_info->evtchn_pending[0]), 0,
sizeof (shared_info->evtchn_pending));
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_data[i].evtchn_pending_sel = 0;
shared_info->vcpu_info[i].evtchn_pending_sel = 0;
/* Copy saved contents of shared-info page. No checking needed. */
page = xc_map_foreign_range(
+1 -1
View File
@@ -524,7 +524,7 @@ static int setup_guest(int xc_handle,
memset(shared_info, 0, sizeof(shared_info_t));
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
munmap(shared_info, PAGE_SIZE);
+1 -1
View File
@@ -198,7 +198,7 @@ static int do_set_shared_page(VCPU *vcpu, u64 gpa)
if (o_info) {
memcpy((void*)d->shared_info, (void*)o_info, PAGE_SIZE);
for_each_vcpu(d, v) {
v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id];
v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
}
/* If original page belongs to xen heap, then relinguish back
* to xen heap. Or else, leave to domain itself to decide.
+3 -3
View File
@@ -205,7 +205,7 @@ void arch_do_createdomain(struct vcpu *v)
printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs);
memset(d->vcpu.arch.privregs, 0, PAGE_SIZE);
#endif
v->vcpu_info = &(d->shared_info->vcpu_data[0]);
v->vcpu_info = &(d->shared_info->vcpu_info[0]);
d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME
@@ -867,7 +867,7 @@ int construct_dom0(struct domain *d,
/* Mask all upcalls... */
for ( i = 1; i < MAX_VIRT_CPUS; i++ )
d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
#ifdef VALIDATE_VT
/* Construct a frame-allocation list for the initial domain, since these
@@ -997,7 +997,7 @@ int construct_domU(struct domain *d,
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
/* Copy the OS image. */
printk("calling loaddomainelfimage(%p,%p)\n",d,image_start);
+1 -1
View File
@@ -266,7 +266,7 @@ void arch_do_createdomain(struct vcpu *v)
d->shared_info = alloc_xenheap_page();
memset(d->shared_info, 0, PAGE_SIZE);
v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id];
v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
v->cpumap = CPUMAP_RUNANYWHERE;
SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
+1 -1
View File
@@ -597,7 +597,7 @@ int construct_dom0(struct domain *d,
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
for ( i = 1; i < num_online_cpus(); i++ )
(void)alloc_vcpu(d, i, i);
+1 -1
View File
@@ -432,7 +432,7 @@ void __init __start_xen(multiboot_info_t *mbi)
BUG_ON(sizeof(start_info_t) > PAGE_SIZE);
BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
BUG_ON(sizeof(vcpu_info_t) != (sizeof(unsigned long) * 4));
BUG_ON(sizeof(vcpu_info_t) != 64);
init_frametable();
+6 -3
View File
@@ -683,8 +683,11 @@ static inline void version_update_end(u32 *version)
static inline void __update_dom_time(struct vcpu *v)
{
struct cpu_time *t = &cpu_time[smp_processor_id()];
struct vcpu_time_info *u = &v->domain->shared_info->vcpu_time[v->vcpu_id];
struct cpu_time *t;
struct vcpu_time_info *u;
t = &cpu_time[smp_processor_id()];
u = &v->domain->shared_info->vcpu_info[v->vcpu_id].time;
version_update_begin(&u->version);
@@ -698,7 +701,7 @@ static inline void __update_dom_time(struct vcpu *v)
void update_dom_time(struct vcpu *v)
{
if ( v->domain->shared_info->vcpu_time[v->vcpu_id].tsc_timestamp !=
if ( v->domain->shared_info->vcpu_info[v->vcpu_id].time.tsc_timestamp !=
cpu_time[smp_processor_id()].local_tsc_stamp )
__update_dom_time(v);
}
+1 -1
View File
@@ -115,7 +115,7 @@ struct vcpu *alloc_vcpu(
if ( vcpu_id != 0 )
{
v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id];
v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
d->vcpu[v->vcpu_id-1]->next_in_list = v;
set_bit(_VCPUF_down, &v->vcpu_flags);
}
+1 -1
View File
@@ -134,7 +134,7 @@ typedef struct arch_shared_info {
typedef struct {
unsigned long cr2;
unsigned long pad; /* sizeof(vcpu_info_t) == 16 */
unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */
} arch_vcpu_info_t;
#endif
+1 -1
View File
@@ -203,7 +203,7 @@ typedef struct arch_shared_info {
typedef struct {
unsigned long cr2;
unsigned long pad; /* sizeof(vcpu_info_t) == 32 */
unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
} arch_vcpu_info_t;
#endif /* !__ASSEMBLY__ */
+2 -2
View File
@@ -72,8 +72,8 @@ struct t_rec {
* field, indexes into an array of struct t_rec's.
*/
struct t_buf {
unsigned int cons; /* Next item to be consumed by control tools. */
unsigned int prod; /* Next item to be produced by Xen. */
uint32_t cons; /* Next item to be consumed by control tools. */
uint32_t prod; /* Next item to be produced by Xen. */
/* 'nr_recs' records follow immediately after the meta-data header. */
};
+28 -31
View File
@@ -266,10 +266,31 @@ typedef struct
*/
#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)
/*
* Per-VCPU information goes here. This will be cleaned up more when Xen
* actually supports multi-VCPU guests.
*/
typedef struct vcpu_time_info {
/*
* Updates to the following values are preceded and followed by an
* increment of 'version'. The guest can therefore detect updates by
* looking for changes to 'version'. If the least-significant bit of
* the version number is set then an update is in progress and the guest
* must wait to read a consistent set of values.
* The correct way to interact with the version number is similar to
* Linux's seqlock: see the implementations of read_seqbegin/read_seqretry.
*/
uint32_t version;
uint32_t pad0;
uint64_t tsc_timestamp; /* TSC at last update of time vals. */
uint64_t system_time; /* Time, in nanosecs, since boot. */
/*
* Current system time:
* system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul
* CPU frequency (Hz):
* ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
*/
uint32_t tsc_to_system_mul;
int8_t tsc_shift;
int8_t pad1[3];
} vcpu_time_info_t; /* 32 bytes */
typedef struct vcpu_info {
/*
* 'evtchn_upcall_pending' is written non-zero by Xen to indicate
@@ -300,39 +321,15 @@ typedef struct vcpu_info {
uint8_t evtchn_upcall_mask;
unsigned long evtchn_pending_sel;
arch_vcpu_info_t arch;
} vcpu_info_t;
typedef struct vcpu_time_info {
/*
* Updates to the following values are preceded and followed by an
* increment of 'version'. The guest can therefore detect updates by
* looking for changes to 'version'. If the least-significant bit of
* the version number is set then an update is in progress and the guest
* must wait to read a consistent set of values.
* The correct way to interact with the version number is similar to
* Linux's seqlock: see the implementations of read_seqbegin/read_seqretry.
*/
uint32_t version;
uint64_t tsc_timestamp; /* TSC at last update of time vals. */
uint64_t system_time; /* Time, in nanosecs, since boot. */
/*
* Current system time:
* system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul
* CPU frequency (Hz):
* ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
*/
uint32_t tsc_to_system_mul;
int8_t tsc_shift;
} vcpu_time_info_t;
vcpu_time_info_t time;
} vcpu_info_t; /* 64 bytes (x86) */
/*
* Xen/kernel shared data -- pointer provided in start_info.
* NB. We expect that this struct is smaller than a page.
*/
typedef struct shared_info {
vcpu_info_t vcpu_data[MAX_VIRT_CPUS];
vcpu_time_info_t vcpu_time[MAX_VIRT_CPUS];
vcpu_info_t vcpu_info[MAX_VIRT_CPUS];
/*
* A domain can create "event channels" on which it can send and receive
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.