[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Core support for memory events.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1261031275 0 # Node ID a1ab94c514b80b3f0845465752ed72cfe4fafa73 # Parent 49ad2a499edba92874590ecf72a7c7d216576099 Core support for memory events. This includes enable/disable, ring functions, and vcpu pause/unpause. Signed-off-by: Patrick Colp <Patrick.Colp@xxxxxxxxxx> --- xen/arch/x86/mm/Makefile | 1 xen/arch/x86/mm/mem_event.c | 199 ++++++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/mem_event.h | 68 +++++++++++++ 3 files changed, 268 insertions(+) diff -r 49ad2a499edb -r a1ab94c514b8 xen/arch/x86/mm/Makefile --- a/xen/arch/x86/mm/Makefile Thu Dec 17 06:27:55 2009 +0000 +++ b/xen/arch/x86/mm/Makefile Thu Dec 17 06:27:55 2009 +0000 @@ -6,6 +6,7 @@ obj-y += guest_walk_2.o obj-y += guest_walk_2.o obj-y += guest_walk_3.o obj-$(x86_64) += guest_walk_4.o +obj-y += mem_event.o guest_walk_%.o: guest_walk.c Makefile $(CC) $(CFLAGS) -DGUEST_PAGING_LEVELS=$* -c $< -o $@ diff -r 49ad2a499edb -r a1ab94c514b8 xen/arch/x86/mm/mem_event.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/mm/mem_event.c Thu Dec 17 06:27:55 2009 +0000 @@ -0,0 +1,199 @@ +/****************************************************************************** + * arch/x86/mm/mem_event.c + * + * Memory event support. + * + * Copyright (c) 2009 Citrix (R)&D) Ltd. (Patrick Colp) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include <xen/event.h> +#include <asm/p2m.h> +#include <asm/mem_event.h> + + +#define xen_mb() mb() +#define xen_rmb() rmb() +#define xen_wmb() wmb() + + +#define MEM_EVENT_RING_THRESHOLD 4 + + +static void mem_event_notify(struct domain *d) +{ + prepare_wait_on_xen_event_channel(d->mem_event.xen_port); + notify_via_xen_event_channel(d->mem_event.xen_port); +} + + +int mem_event_enable(struct domain *d, mfn_t ring_mfn, mfn_t shared_mfn) +{ + int rc; + + /* Map ring and shared pages */ + d->mem_event.ring_page = map_domain_page(mfn_x(ring_mfn)); + if ( d->mem_event.ring_page == NULL ) + goto err; + + d->mem_event.shared_page = map_domain_page(mfn_x(shared_mfn)); + if ( d->mem_event.shared_page == NULL ) + goto err_ring; + + /* Allocate event channel */ + rc = alloc_unbound_xen_event_channel(d->vcpu[0], + current->domain->domain_id); + if ( rc < 0 ) + goto err_shared; + + ((mem_event_shared_page_t *)d->mem_event.shared_page)->port = rc; + d->mem_event.xen_port = rc; + + /* Initialise tasklet */ + tasklet_init(&d->mem_event.tasklet, + (void(*)(unsigned long))mem_event_notify, + (unsigned long)d); + + /* Prepare ring buffer */ + FRONT_RING_INIT(&d->mem_event.front_ring, + (mem_event_sring_t *)d->mem_event.ring_page, + PAGE_SIZE); + + mem_event_ring_lock_init(d); + + d->mem_event.paused = 0; + d->mem_event.enabled = 1; + + return 0; + + err_shared: + unmap_domain_page(d->mem_event.shared_page); + d->mem_event.shared_page = NULL; + err_ring: + unmap_domain_page(d->mem_event.ring_page); + d->mem_event.ring_page = NULL; + err: + return 1; +} + +int mem_event_disable(struct domain *d) +{ + d->mem_event.enabled = 0; + d->mem_event.paused = 0; + + unmap_domain_page(d->mem_event.ring_page); + d->mem_event.ring_page = NULL; + + unmap_domain_page(d->mem_event.shared_page); + d->mem_event.shared_page = NULL; + + return 0; +} + +void mem_event_put_request(struct domain *d, mem_event_request_t *req) +{ + mem_event_front_ring_t *front_ring; + RING_IDX req_prod; + + mem_event_ring_lock(d); + + front_ring = &d->mem_event.front_ring; + req_prod = front_ring->req_prod_pvt; + + /* Copy request */ + memcpy(RING_GET_REQUEST(front_ring, req_prod), req, sizeof(*req)); + req_prod++; + + /* Update ring */ + front_ring->req_prod_pvt = req_prod; + RING_PUSH_REQUESTS(front_ring); + + mem_event_ring_unlock(d); + + tasklet_schedule(&d->mem_event.tasklet); +} + +void mem_event_get_response(struct domain *d, mem_event_response_t *rsp) +{ + mem_event_front_ring_t *front_ring; + RING_IDX rsp_cons; + + mem_event_ring_lock(d); + + front_ring = &d->mem_event.front_ring; + rsp_cons = front_ring->rsp_cons; + + /* Copy response */ + memcpy(rsp, RING_GET_RESPONSE(front_ring, rsp_cons), sizeof(*rsp)); + rsp_cons++; + + /* Update ring */ + front_ring->rsp_cons = rsp_cons; + front_ring->sring->rsp_event = rsp_cons + 1; + + mem_event_ring_unlock(d); +} + +void mem_event_unpause_vcpus(struct domain *d) +{ + struct vcpu *v; + + for_each_vcpu(d, v) + { + if ( d->mem_event.paused_vcpus[v->vcpu_id] ) + { + vcpu_unpause(v); + d->mem_event.paused_vcpus[v->vcpu_id] = 0; + } + } +} + +int mem_event_pause_vcpu(struct domain *d, struct vcpu *v) +{ + vcpu_pause_nosync(v); + d->mem_event.paused_vcpus[v->vcpu_id] = 1; + + return 0; +} + +int mem_event_check_ring(struct domain *d) +{ + int free_requests; + int ring_full; + + mem_event_ring_lock(d); + + free_requests = RING_FREE_REQUESTS(&d->mem_event.front_ring); + ring_full = free_requests < MEM_EVENT_RING_THRESHOLD; + + if ( (current->domain->domain_id == d->domain_id) && ring_full ) + mem_event_pause_vcpu(d, current); + + mem_event_ring_unlock(d); + + return ring_full; +} + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 49ad2a499edb -r a1ab94c514b8 xen/include/asm-x86/mem_event.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/mem_event.h Thu Dec 17 06:27:55 2009 +0000 @@ -0,0 +1,68 @@ +/****************************************************************************** + * include/asm-x86/mem_event.h + * + * Common interface for memory event support. + * + * Copyright (c) 2009 Citrix (R&D) Ltd. (Patrick Colp) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef __MEM_EVENT_H__ +#define __MEM_EVENT_H__ + + +/* Printouts */ +#define MEM_EVENT_PRINTK(_f, _a...) \ + debugtrace_printk("mem_event: %s(): " _f, __func__, ##_a) +#define MEM_EVENT_ERROR(_f, _a...) \ + printk("mem_event error: %s(): " _f, __func__, ##_a) +#define MEM_EVENT_DEBUG(flag, _f, _a...) \ + do { \ + if (MEM_EVENT_DEBUG_ ## flag) \ + debugtrace_printk("mem_event debug: %s(): " _f, __func__, ##_a); \ + } while (0) + + +#define mem_event_enabled(_d) (_d)->mem_event.enabled + + +/* Ring lock */ +#define mem_event_ring_lock_init(_d) spin_lock_init(&(_d)->mem_event.ring_lock) +#define mem_event_ring_lock(_d) spin_lock(&(_d)->mem_event.ring_lock) +#define mem_event_ring_unlock(_d) spin_unlock(&(_d)->mem_event.ring_lock) + + +int mem_event_enable(struct domain *d, mfn_t ring_mfn, mfn_t shared_mfn); +int mem_event_disable(struct domain *d); + +int mem_event_check_ring(struct domain *d); +void mem_event_put_request(struct domain *d, mem_event_request_t *req); +void mem_event_get_response(struct domain *d, mem_event_response_t *rsp); +void mem_event_unpause_vcpus(struct domain *d); + + +#endif /* __MEM_EVENT_H__ */ + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |