[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH V5 03/15] evtchn: alter internal object handling scheme
Originally, evtchn objects are stored in buckets. Now we add another layer called group. Now struct domain holds an array to evtchn groups, then each group holds pointers to a bucket. With this change, we can handle more struct evtchn in a space-efficient way. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- xen/common/event_channel.c | 26 +++++++++++++++++++++++--- xen/include/xen/event.h | 12 ++++++++++-- xen/include/xen/sched.h | 12 +++++++++--- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 1b702d5..76de8ec 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -124,6 +124,7 @@ static int virq_is_global(uint32_t virq) static int get_free_port(struct domain *d) { struct evtchn *chn; + struct evtchn **grp; int port; int i, j; @@ -137,6 +138,15 @@ static int get_free_port(struct domain *d) if ( port == MAX_EVTCHNS(d) ) return -ENOSPC; + if ( unlikely(group_from_port(d, port) == NULL ) ) + { + grp = xzalloc_array(struct evtchn *, BUCKETS_PER_GROUP); + if ( unlikely(grp == NULL) ) + return -ENOMEM; + else + group_from_port(d, port) = grp; + } + chn = xzalloc_array(struct evtchn, EVTCHNS_PER_BUCKET); if ( unlikely(chn == NULL) ) return -ENOMEM; @@ -1191,7 +1201,7 @@ int evtchn_init(struct domain *d) void evtchn_destroy(struct domain *d) { - int i; + int i, j; /* After this barrier no new event-channel allocations can occur. */ BUG_ON(!d->is_dying); @@ -1206,9 +1216,19 @@ void evtchn_destroy(struct domain *d) /* Free all event-channel buckets. */ spin_lock(&d->event_lock); - for ( i = 0; i < NR_EVTCHN_BUCKETS; i++ ) + for ( i = 0; i < NR_EVTCHN_GROUPS; i++ ) { - xsm_free_security_evtchn(d->evtchn[i]); + if ( d->evtchn[i] == NULL ) + continue; + + for ( j = 0; j < BUCKETS_PER_GROUP; j++ ) + { + if ( d->evtchn[i][j] == NULL ) + continue; + xsm_free_security_evtchn(d->evtchn[i][j]); + xfree(d->evtchn[i][j]); + d->evtchn[i][j] = NULL; + } xfree(d->evtchn[i]); d->evtchn[i] = NULL; } diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index 65ac81a..ff9332a 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -69,11 +69,19 @@ int guest_enabled_event(struct vcpu *v, uint32_t virq); /* Notify remote end of a Xen-attached event channel.*/ void notify_via_xen_event_channel(struct domain *ld, int lport); -/* Internal event channel object accessors */ +/* + * Internal event channel object storage: + * Objects are organized in two level scheme: group and bucket + * A group consists of several buckets, a bucket is an array of struct evtchn + */ +#define group_from_port(d,p) \ + ((d)->evtchn[(p)/EVTCHNS_PER_GROUP]) +/* User should make sure group is not NULL */ #define bucket_from_port(d,p) \ - ((d)->evtchn[(p)/EVTCHNS_PER_BUCKET]) + ((group_from_port(d,p))[((p)%EVTCHNS_PER_GROUP)/EVTCHNS_PER_BUCKET]) #define port_is_valid(d,p) \ (((p) >= 0) && ((p) < MAX_EVTCHNS(d)) && \ + (group_from_port(d,p) != NULL) && \ (bucket_from_port(d,p) != NULL)) #define evtchn_from_port(d,p) \ (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)]) diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index ae3cd07..7169ca0 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -51,8 +51,14 @@ extern struct domain *dom0; #define BITS_PER_EVTCHN_WORD(d) (has_32bit_shinfo(d) ? 32 : BITS_PER_XEN_ULONG) #endif #define MAX_EVTCHNS(d) (BITS_PER_EVTCHN_WORD(d) * BITS_PER_EVTCHN_WORD(d)) -#define EVTCHNS_PER_BUCKET 128 -#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET) +/* + * To make sure EVTCHNS_PER_BUCKET is at least 1 for 32 bit build, + * NR_EVTCHN_GROUPS * BUCKETES_PER_GROUP should be <= 1024. + */ +#define NR_EVTCHN_GROUPS 64 +#define BUCKETS_PER_GROUP 16 +#define EVTCHNS_PER_GROUP (NR_EVENT_CHANNELS / NR_EVTCHN_GROUPS) +#define EVTCHNS_PER_BUCKET (EVTCHNS_PER_GROUP / BUCKETS_PER_GROUP) struct evtchn { @@ -260,7 +266,7 @@ struct domain spinlock_t rangesets_lock; /* Event channel information. */ - struct evtchn *evtchn[NR_EVTCHN_BUCKETS]; + struct evtchn **evtchn[NR_EVTCHN_GROUPS]; spinlock_t event_lock; struct grant_table *grant_table; -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |