From 3842b056dabe54df9cd7f77aa2ce6767d14e0740 Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Wed, 24 Jun 2009 14:23:25 +0100 Subject: [PATCH] Pre-allocate a pool of grant references and pull from them, rather than pulling from the main pool for every packet. --- drivers/xen/core/gnttab.c | 35 ++++++++++++++++++++++++++++++++++ drivers/xen/netchannel2/rscb.c | 4 +++- drivers/xen/netchannel2/util.c | 8 +++++--- include/xen/gnttab.h | 5 +++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/drivers/xen/core/gnttab.c b/drivers/xen/core/gnttab.c index 044a8761..ba1433a5 100644 --- a/drivers/xen/core/gnttab.c +++ b/drivers/xen/core/gnttab.c @@ -522,6 +522,41 @@ void gnttab_free_grant_references(grant_ref_t head) } EXPORT_SYMBOL_GPL(gnttab_free_grant_references); +int gnttab_suballoc_grant_references(u16 count, grant_ref_t *old_head, + grant_ref_t *new_head) +{ + grant_ref_t cursor; + unsigned nr_allocated; + + *new_head = cursor = *old_head; + if (cursor == GNTTAB_LIST_END) + return -ENOSPC; + nr_allocated = 1; + while (nr_allocated < count) { + cursor = gnttab_entry(cursor); + if (cursor == GNTTAB_LIST_END) + return -ENOSPC; + nr_allocated++; + } + *old_head = gnttab_entry(cursor); + gnttab_entry(cursor) = GNTTAB_LIST_END; + return 0; +} +EXPORT_SYMBOL_GPL(gnttab_suballoc_grant_references); + +void gnttab_subfree_grant_references(grant_ref_t head, grant_ref_t *pool) +{ + grant_ref_t cursor; + + for (cursor = head; + gnttab_entry(cursor) != GNTTAB_LIST_END; + cursor = gnttab_entry(cursor)) + ; + gnttab_entry(cursor) = *pool; + *pool = head; +} +EXPORT_SYMBOL_GPL(gnttab_subfree_grant_references); + int gnttab_alloc_grant_references(u16 count, grant_ref_t *head) { int h = get_free_entries(count); diff --git a/drivers/xen/netchannel2/rscb.c b/drivers/xen/netchannel2/rscb.c index 038086c8..2130d3a2 100644 --- a/drivers/xen/netchannel2/rscb.c +++ b/drivers/xen/netchannel2/rscb.c @@ -315,7 +315,9 @@ int prepare_xmit_allocate_grant(struct netchannel2_ring_pair *ncrp, } /* Grab the grant references. */ - err = gnttab_alloc_grant_references(skb_co->nr_fragments, &gref_pool); + err = gnttab_suballoc_grant_references(skb_co->nr_fragments, + &ncrp->gref_pool, + &gref_pool); if (err < 0) { release_txp_slot(ncrp, skb); /* Leave skb_co->nr_fragments set, so that we don't diff --git a/drivers/xen/netchannel2/util.c b/drivers/xen/netchannel2/util.c index edef7f6b..d6b985f3 100644 --- a/drivers/xen/netchannel2/util.c +++ b/drivers/xen/netchannel2/util.c @@ -336,7 +336,7 @@ void release_tx_packet(struct netchannel2_ring_pair *ncrp, while (!nc2_end_foreign_access_ref(gref, 1)) { cpu_relax(); } - gnttab_free_grant_reference(gref); + gnttab_release_grant_reference(&ncrp->gref_pool, gref); } } else if (skb_co->type == NC2_PACKET_TYPE_receiver_map) { while (1) { @@ -348,11 +348,13 @@ void release_tx_packet(struct netchannel2_ring_pair *ncrp, if (r == 0) { printk(KERN_WARNING "Failed to end remote access to packet memory.\n"); } else { - gnttab_free_grant_reference(gref); + gnttab_release_grant_reference(&ncrp->gref_pool, + gref); } } } else if (skb_co->gref_pool != 0) { - gnttab_free_grant_references(skb_co->gref_pool); + gnttab_subfree_grant_references(skb_co->gref_pool, + &ncrp->gref_pool); } if (tp != NULL) diff --git a/include/xen/gnttab.h b/include/xen/gnttab.h index a5277357..bb9f020a 100644 --- a/include/xen/gnttab.h +++ b/include/xen/gnttab.h @@ -94,10 +94,15 @@ int gnttab_query_foreign_access(grant_ref_t ref); */ int gnttab_alloc_grant_references(u16 count, grant_ref_t *pprivate_head); +int gnttab_suballoc_grant_references(u16 count, grant_ref_t *old_head, + grant_ref_t *new_head); + void gnttab_free_grant_reference(grant_ref_t ref); void gnttab_free_grant_references(grant_ref_t head); +void gnttab_subfree_grant_references(grant_ref_t head, grant_ref_t *pool); + int gnttab_empty_grant_references(const grant_ref_t *pprivate_head); int gnttab_claim_grant_reference(grant_ref_t *pprivate_head); -- 2.39.5