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))){
#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]);
{
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--;
nc2_vmq_unmap_buf(nc, idx, 1);
}
+ vmq_flush_unmap_grants();
+
vmq->mapped_pages_cons = cons;
}
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;
}
/* 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;
}