Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
xen.2142
5587d779-evtchn-defer-freeing-struct-evtchn-s-u...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5587d779-evtchn-defer-freeing-struct-evtchn-s-until-evtchn_destroy_final.patch of Package xen.2142
# Commit a753f0e53ff973a8a066e86c1cb3d6dd5c68d59f # Date 2015-06-22 11:38:01 +0200 # Author David Vrabel <david.vrabel@citrix.com> # Committer Jan Beulich <jbeulich@suse.com> evtchn: defer freeing struct evtchn's until evtchn_destroy_final() notify_via_xen_event_channel() and free_xen_event_channel() had to check if the domain was dying because they may be called while the domain is being destroyed and the struct evtchn's are being freed. By deferring the freeing of the struct evtchn's until all references to the domain are dropped, these functions can rely on the channel state being present and valid. Signed-off-by: David Vrabel <david.vrabel@citrix.com> --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -1174,22 +1174,8 @@ int alloc_unbound_xen_event_channel( void free_xen_event_channel( struct vcpu *local_vcpu, int port) { - struct evtchn *chn; struct domain *d = local_vcpu->domain; - - spin_lock(&d->event_lock); - - if ( unlikely(d->is_dying) ) - { - spin_unlock(&d->event_lock); - return; - } - BUG_ON(!port_is_valid(d, port)); - chn = evtchn_from_port(d, port); - BUG_ON(!consumer_is_xen(chn)); - - spin_unlock(&d->event_lock); evtchn_close(d, port, 0); } @@ -1203,18 +1189,12 @@ void notify_via_xen_event_channel(struct spin_lock(&ld->event_lock); - if ( unlikely(ld->is_dying) ) - { - spin_unlock(&ld->event_lock); - return; - } - ASSERT(port_is_valid(ld, lport)); lchn = evtchn_from_port(ld, lport); - ASSERT(consumer_is_xen(lchn)); if ( likely(lchn->state == ECS_INTERDOMAIN) ) { + ASSERT(consumer_is_xen(lchn)); rd = lchn->u.interdomain.remote_dom; rport = lchn->u.interdomain.remote_port; rchn = evtchn_from_port(rd, rport); @@ -1282,7 +1262,7 @@ int evtchn_init(struct domain *d) void evtchn_destroy(struct domain *d) { - unsigned int i, j; + unsigned int i; /* After this barrier no new event-channel allocations can occur. */ BUG_ON(!d->is_dying); @@ -1292,8 +1272,17 @@ void evtchn_destroy(struct domain *d) for ( i = 0; port_is_valid(d, i); i++ ) evtchn_close(d, i, 0); + clear_global_virq_handlers(d); + + evtchn_fifo_destroy(d); +} + + +void evtchn_destroy_final(struct domain *d) +{ + unsigned int i, j; + /* Free all event-channel buckets. */ - spin_lock(&d->event_lock); for ( i = 0; i < NR_EVTCHN_GROUPS; i++ ) { if ( !d->evtchn_group[i] ) @@ -1301,20 +1290,9 @@ void evtchn_destroy(struct domain *d) for ( j = 0; j < BUCKETS_PER_GROUP; j++ ) free_evtchn_bucket(d, d->evtchn_group[i][j]); xfree(d->evtchn_group[i]); - d->evtchn_group[i] = NULL; } free_evtchn_bucket(d, d->evtchn); - d->evtchn = NULL; - spin_unlock(&d->event_lock); - clear_global_virq_handlers(d); - - evtchn_fifo_destroy(d); -} - - -void evtchn_destroy_final(struct domain *d) -{ #if MAX_VIRT_CPUS > BITS_PER_LONG xfree(d->poll_mask); d->poll_mask = NULL;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor