From: Steven Smith Date: Wed, 26 Aug 2009 14:43:51 +0000 (+0100) Subject: Batch vmq unmap grant operations. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=refs%2Fheads%2Fnapi-plus-vmdq;p=people%2Fssmith%2Fnc2-2.6.27.git Batch vmq unmap grant operations. Signed-off-by: Jose Renato Santos --- diff --git a/drivers/xen/netchannel2/chan.c b/drivers/xen/netchannel2/chan.c index 98a1f908..185f6221 100644 --- a/drivers/xen/netchannel2/chan.c +++ b/drivers/xen/netchannel2/chan.c @@ -894,10 +894,13 @@ static int process_ring(struct napi_struct *napi, This must happen before we flush the rings, since that's when the PACKET messages will be made visible to the other end. */ - if (ncrp == &nc->rings) + if (ncrp == &nc->rings) { flush_hypercall_batcher(&nc->batcher, nc2_posted_on_gntcopy_fail); - +#ifdef CONFIG_XEN_NETDEV2_VMQ + vmq_flush_unmap_hypercall(); +#endif + } flush_rings(ncrp); while ((skb = __skb_dequeue(&ncrp->release_on_flush_batcher))){ diff --git a/drivers/xen/netchannel2/vmq.c b/drivers/xen/netchannel2/vmq.c index 6ef65393..39b07b59 100644 --- a/drivers/xen/netchannel2/vmq.c +++ b/drivers/xen/netchannel2/vmq.c @@ -47,6 +47,39 @@ #define VMQ_QUEUE_ENABLED 2 #define VMQ_QUEUE_CLOSING 3 +#define VMQ_MAX_UNMAP_OPS 256 +struct vmq_unmap_grants { + unsigned n; + gnttab_unmap_grant_ref_t gop[VMQ_MAX_UNMAP_OPS]; +}; +typedef struct vmq_unmap_grants vmq_unmap_grants_t; + +vmq_unmap_grants_t vmq_unmap_grants; + +static inline void vmq_flush_unmap_grants(void) +{ + if (vmq_unmap_grants.n == 0) + return; + + if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, + vmq_unmap_grants.gop, + vmq_unmap_grants.n)) + BUG(); + vmq_unmap_grants.n = 0; +} + +static inline gnttab_unmap_grant_ref_t *vmq_next_unmap_gop(void) +{ + if (vmq_unmap_grants.n == VMQ_MAX_UNMAP_OPS) + vmq_flush_unmap_grants(); + return &vmq_unmap_grants.gop[vmq_unmap_grants.n++]; +} + +void vmq_flush_unmap_hypercall(void) +{ + vmq_flush_unmap_grants(); +} + static inline unsigned long vmq_idx_to_pfn(nc2_vmq_t *vmq, unsigned int idx) { return page_to_pfn(vmq->pages[idx]); @@ -271,19 +304,18 @@ static void nc2_vmq_unmap_buf(struct netchannel2 *nc, { nc2_vmq_t *vmq = &nc->vmq; unsigned long pfn; - gnttab_unmap_grant_ref_t gop; + gnttab_unmap_grant_ref_t *gop; unsigned prod; - int ret; pfn = vmq_idx_to_pfn(vmq, idx); /* Already unmapped? */ if (!phys_to_machine_mapping_valid(pfn)) return; - gnttab_set_unmap_op(&gop, vmq_idx_to_kaddr(vmq, idx), + + gop = vmq_next_unmap_gop(); + gnttab_set_unmap_op(gop, vmq_idx_to_kaddr(vmq, idx), GNTMAP_host_map, vmq->buffer[idx].buf->grant_handle); - ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &gop, 1); - BUG_ON(ret); vmq->nbufs--; @@ -321,6 +353,8 @@ static void nc2_vmq_free_mapped_bufs(struct netchannel2 *nc) nc2_vmq_unmap_buf(nc, idx, 1); } + vmq_flush_unmap_grants(); + vmq->mapped_pages_cons = cons; } @@ -342,7 +376,9 @@ static void nc2_vmq_free_skb(struct sk_buff *skb) idx = nc2_vmq_page_index(frags[i].page); nc2_vmq_unmap_buf(nc, idx, 1); } - + + vmq_flush_unmap_grants(); + shinfo->frag_list = NULL; shinfo->nr_frags = 0; @@ -762,7 +798,7 @@ void xmit_vmq(struct netchannel2 *nc, struct sk_buff *skb, } /* Avoid unmapping frags grants when skb is freed later */ - /* by nc2_vmq_fre_skb() */ + /* by nc2_vmq_free_skb() */ skb_shinfo(skb)->nr_frags = 0; } diff --git a/drivers/xen/netchannel2/vmq.h b/drivers/xen/netchannel2/vmq.h index 0af7924e..91cba694 100644 --- a/drivers/xen/netchannel2/vmq.h +++ b/drivers/xen/netchannel2/vmq.h @@ -9,6 +9,7 @@ void do_vmq_work(struct netchannel2 *nc); int nc2_is_vmq_packet(struct netchannel2 *nc, struct sk_buff *skb); void xmit_vmq(struct netchannel2 *nc, struct sk_buff *skb, volatile void *msg); +void vmq_flush_unmap_hypercall(void); #define vmq_get(_b) \ atomic_inc(&(_b)->refcnt);