|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCHv6 4/5] gnttab: remove unnecessary grant table locks
From: Malcolm Crossley <malcolm.crossley@xxxxxxxxxx>
The grant table lock is not required to protect reads of the
table version, the active entry array, or the map track array.
This is safe because: a) the grant table version only changes once
from 0 to 1 or 2; b) the active entry array only grows; and c) the map
track array only grows.
Signed-off-by: Malcolm Crossley <malcolm.crossley@xxxxxxxxxx>
Signed-off-by: David Vrabel <david.vrabel@xxxxxxxxxx>
---
xen/common/grant_table.c | 76 +++++++++--------------------------------
xen/include/xen/grant_table.h | 8 ++---
2 files changed, 21 insertions(+), 63 deletions(-)
diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index a5470c8..8f3d125 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -196,8 +196,6 @@ active_entry_acquire(struct grant_table *t, grant_ref_t e)
{
struct active_grant_entry *act;
- ASSERT(spin_is_locked(&t->lock));
-
act = &_active_entry(t, e);
spin_lock(&act->lock);
@@ -647,7 +645,6 @@ __gnttab_map_grant_ref(
}
rgt = rd->grant_table;
- spin_lock(&rgt->lock);
if ( rgt->gt_version == 0 )
PIN_FAIL(unlock_out, GNTST_general_error,
@@ -827,7 +824,6 @@ __gnttab_map_grant_ref(
mt->flags = op->flags;
active_entry_release(act);
- spin_unlock(&rgt->lock);
op->dev_bus_addr = (u64)frame << PAGE_SHIFT;
op->handle = handle;
@@ -869,7 +865,6 @@ __gnttab_map_grant_ref(
active_entry_release(act);
unlock_out:
- spin_unlock(&rgt->lock);
op->status = rc;
put_maptrack_handle(lgt, handle);
rcu_unlock_domain(rd);
@@ -919,18 +914,15 @@ __gnttab_unmap_common(
}
op->map = &maptrack_entry(lgt, op->handle);
- spin_lock(&lgt->lock);
if ( unlikely(!op->map->flags) )
{
- spin_unlock(&lgt->lock);
gdprintk(XENLOG_INFO, "Zero flags for handle (%d).\n", op->handle);
op->status = GNTST_bad_handle;
return;
}
dom = op->map->domid;
- spin_unlock(&lgt->lock);
if ( unlikely((rd = rcu_lock_domain_by_id(dom)) == NULL) )
{
@@ -952,7 +944,6 @@ __gnttab_unmap_common(
rgt = rd->grant_table;
- spin_lock(&rgt->lock);
act = active_entry_acquire(rgt, op->map->ref);
op->flags = op->map->flags;
@@ -1023,7 +1014,6 @@ __gnttab_unmap_common(
act_release_out:
active_entry_release(act);
- spin_unlock(&rgt->lock);
op->status = rc;
rcu_unlock_domain(rd);
@@ -1055,7 +1045,6 @@ __gnttab_unmap_common_complete(struct gnttab_unmap_common
*op)
rcu_lock_domain(rd);
rgt = rd->grant_table;
- spin_lock(&rgt->lock);
if ( rgt->gt_version == 0 )
goto unlock_out;
@@ -1122,8 +1111,6 @@ __gnttab_unmap_common_complete(struct gnttab_unmap_common
*op)
active_entry_release(act);
unlock_out:
- spin_unlock(&rgt->lock);
-
if ( put_handle )
{
op->map->flags = 0;
@@ -1277,7 +1264,7 @@ gnttab_populate_status_frames(struct domain *d, struct
grant_table *gt,
for ( i = nr_status_frames(gt); i < req_status_frames; i++ )
gnttab_create_status_page(d, gt, i);
- gt->nr_status_frames = req_status_frames;
+ atomic_set(>->nr_status_frames, req_status_frames);
return 0;
@@ -1306,7 +1293,7 @@ gnttab_unpopulate_status_frames(struct domain *d, struct
grant_table *gt)
free_xenheap_page(gt->status[i]);
gt->status[i] = NULL;
}
- gt->nr_status_frames = 0;
+ atomic_set(>->nr_status_frames, 0);
}
/*
@@ -1356,7 +1343,7 @@ gnttab_grow_table(struct domain *d, unsigned int
req_nr_frames)
/* Share the new shared frames with the recipient domain */
for ( i = nr_grant_frames(gt); i < req_nr_frames; i++ )
gnttab_create_shared_page(d, gt, i);
- gt->nr_grant_frames = req_nr_frames;
+ atomic_set(>->nr_grant_frames, req_nr_frames);
return 1;
@@ -1423,7 +1410,17 @@ gnttab_setup_table(
}
gt = d->grant_table;
- spin_lock(>->lock);
+
+ /* Tracking of mapped foreign frames table */
+ if ( (gt->maptrack = xzalloc_array(struct grant_mapping *,
+ max_maptrack_frames * d->max_vcpus)) ==
NULL )
+ goto out2;
+ for_each_vcpu( d, v )
+ {
+ v->maptrack_head = MAPTRACK_TAIL;
+ v->maptrack_tail = MAPTRACK_TAIL;
+ }
+ gt->maptrack_pages = 0;
if ( gt->gt_version == 0 )
gt->gt_version = 1;
@@ -1437,7 +1434,7 @@ gnttab_setup_table(
"Expand grant table to %u failed. Current: %u Max: %u\n",
op.nr_frames, nr_grant_frames(gt), max_grant_frames);
op.status = GNTST_general_error;
- goto out3;
+ goto out2;
}
op.status = GNTST_okay;
@@ -1450,8 +1447,6 @@ gnttab_setup_table(
op.status = GNTST_bad_virt_addr;
}
- out3:
- spin_unlock(>->lock);
out2:
rcu_unlock_domain(d);
out1:
@@ -1525,8 +1520,6 @@ gnttab_prepare_for_transfer(
union grant_combo scombo, prev_scombo, new_scombo;
int retries = 0;
- spin_lock(&rgt->lock);
-
if ( rgt->gt_version == 0 )
{
gdprintk(XENLOG_INFO,
@@ -1575,12 +1568,9 @@ gnttab_prepare_for_transfer(
scombo = prev_scombo;
}
-
- spin_unlock(&rgt->lock);
return 1;
fail:
- spin_unlock(&rgt->lock);
return 0;
}
@@ -1773,8 +1763,6 @@ gnttab_transfer(
TRACE_1D(TRC_MEM_PAGE_GRANT_TRANSFER, e->domain_id);
/* Tell the guest about its new page frame. */
- spin_lock(&e->grant_table->lock);
-
if ( e->grant_table->gt_version == 1 )
{
grant_entry_v1_t *sha = &shared_entry_v1(e->grant_table, gop.ref);
@@ -1791,8 +1779,6 @@ gnttab_transfer(
shared_entry_header(e->grant_table, gop.ref)->flags |=
GTF_transfer_completed;
- spin_unlock(&e->grant_table->lock);
-
rcu_unlock_domain(e);
gop.status = GNTST_okay;
@@ -1829,8 +1815,6 @@ __release_grant_for_copy(
released_read = 0;
released_write = 0;
- spin_lock(&rgt->lock);
-
act = active_entry_acquire(rgt, gref);
sha = shared_entry_header(rgt, gref);
r_frame = act->frame;
@@ -1871,7 +1855,6 @@ __release_grant_for_copy(
}
active_entry_release(act);
- spin_unlock(&rgt->lock);
if ( td != rd )
{
@@ -1929,8 +1912,6 @@ __acquire_grant_for_copy(
*page = NULL;
- spin_lock(&rgt->lock);
-
if ( rgt->gt_version == 0 )
PIN_FAIL(gnt_unlock_out, GNTST_general_error,
"remote grant table not ready\n");
@@ -2005,19 +1986,16 @@ __acquire_grant_for_copy(
* lock here and reacquire
*/
active_entry_release(act);
- spin_unlock(&rgt->lock);
rc = __acquire_grant_for_copy(td, trans_gref, rd->domain_id,
readonly, &grant_frame, page,
&trans_page_off, &trans_length, 0);
- spin_lock(&rgt->lock);
act = active_entry_acquire(rgt, gref);
if ( rc != GNTST_okay ) {
__fixup_status_for_copy_pin(act, status);
active_entry_release(act);
- spin_unlock(&rgt->lock);
rcu_unlock_domain(td);
return rc;
}
@@ -2031,7 +2009,6 @@ __acquire_grant_for_copy(
__fixup_status_for_copy_pin(act, status);
rcu_unlock_domain(td);
active_entry_release(act);
- spin_unlock(&rgt->lock);
put_page(*page);
return __acquire_grant_for_copy(rd, gref, ldom, readonly,
frame, page, page_off, length,
@@ -2100,7 +2077,6 @@ __acquire_grant_for_copy(
*frame = act->frame;
active_entry_release(act);
- spin_unlock(&rgt->lock);
return rc;
unlock_out_clear:
@@ -2115,8 +2091,6 @@ __acquire_grant_for_copy(
active_entry_release(act);
gnt_unlock_out:
- spin_unlock(&rgt->lock);
-
return rc;
}
@@ -2432,7 +2406,6 @@
gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop)
if ( gt->gt_version == op.version )
goto out;
- spin_lock(>->lock);
/* Make sure that the grant table isn't currently in use when we
change the version number, except for the first 8 entries which
are allowed to be in use (xenstore/xenconsole keeps them mapped).
@@ -2642,8 +2615,6 @@ __gnttab_swap_grant_ref(grant_ref_t ref_a, grant_ref_t
ref_b)
*/
return rc;
- spin_lock(>->lock);
-
/* Bounds check on the grant refs */
if ( unlikely(ref_a >= nr_grant_entries(d->grant_table)))
PIN_FAIL(out, GNTST_bad_gntref, "Bad ref-a (%d).\n", ref_a);
@@ -2686,7 +2657,6 @@ out:
active_entry_release(act_b);
if ( act_a != NULL )
active_entry_release(act_a);
- spin_unlock(>->lock);
rcu_unlock_domain(d);
@@ -2757,12 +2727,9 @@ static int __gnttab_cache_flush(gnttab_cache_flush_t
*cflush,
if ( d != owner )
{
- spin_lock(&owner->grant_table->lock);
-
ret = grant_map_exists(d, owner->grant_table, mfn, ref_count);
if ( ret != 0 )
{
- spin_unlock(&owner->grant_table->lock);
rcu_unlock_domain(d);
put_page(page);
return ret;
@@ -2781,8 +2748,6 @@ static int __gnttab_cache_flush(gnttab_cache_flush_t
*cflush,
else
ret = 0;
- if ( d != owner )
- spin_unlock(&owner->grant_table->lock);
unmap_domain_page(v);
put_page(page);
@@ -3003,7 +2968,7 @@ grant_table_create(
/* Simple stuff. */
spin_lock_init(&t->lock);
spin_lock_init(&t->maptrack_lock);
- t->nr_grant_frames = INITIAL_NR_GRANT_FRAMES;
+ atomic_set(&t->nr_grant_frames, INITIAL_NR_GRANT_FRAMES);
/* Active grant table. */
if ( (t->active = xzalloc_array(struct active_grant_entry *,
@@ -3050,7 +3015,7 @@ grant_table_create(
for ( i = 0; i < INITIAL_NR_GRANT_FRAMES; i++ )
gnttab_create_shared_page(d, t, i);
- t->nr_status_frames = 0;
+ atomic_set(&t->nr_status_frames, 0);
/* Okay, install the structure. */
d->grant_table = t;
@@ -3111,8 +3076,6 @@ gnttab_release_mappings(
}
rgt = rd->grant_table;
- spin_lock(&rgt->lock);
-
act = active_entry_acquire(rgt, ref);
sha = shared_entry_header(rgt, ref);
if (rgt->gt_version == 1)
@@ -3172,7 +3135,6 @@ gnttab_release_mappings(
gnttab_clear_flag(_GTF_reading, status);
active_entry_release(act);
- spin_unlock(&rgt->lock);
rcu_unlock_domain(rd);
@@ -3224,8 +3186,6 @@ static void gnttab_usage_print(struct domain *rd)
printk(" -------- active -------- -------- shared --------\n");
printk("[ref] localdom mfn pin localdom gmfn flags\n");
- spin_lock(>->lock);
-
if ( gt->gt_version == 0 )
goto out;
@@ -3277,8 +3237,6 @@ static void gnttab_usage_print(struct domain *rd)
}
out:
- spin_unlock(>->lock);
-
if ( first )
printk("grant-table for remote domain:%5d ... "
"no active grant table entries\n", rd->domain_id);
diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h
index 8ff1883..d78c381 100644
--- a/xen/include/xen/grant_table.h
+++ b/xen/include/xen/grant_table.h
@@ -65,7 +65,7 @@ struct grant_mapping {
/* Per-domain grant information. */
struct grant_table {
/* Table size. Number of frames shared with guest */
- unsigned int nr_grant_frames;
+ atomic_t nr_grant_frames;
/* Shared grant table (see include/public/grant_table.h). */
union {
void **shared_raw;
@@ -73,7 +73,7 @@ struct grant_table {
union grant_entry_v2 **shared_v2;
};
/* Number of grant status frames shared with guest (for version 2) */
- unsigned int nr_status_frames;
+ atomic_t nr_status_frames;
/* State grant table (see include/public/grant_table.h). */
grant_status_t **status;
/* Active grant table. */
@@ -114,13 +114,13 @@ gnttab_grow_table(struct domain *d, unsigned int
req_nr_frames);
/* Number of grant table frames. Caller must hold d's grant table lock. */
static inline unsigned int nr_grant_frames(struct grant_table *gt)
{
- return gt->nr_grant_frames;
+ return atomic_read(>->nr_grant_frames);
}
/* Number of status grant table frames. Caller must hold d's gr. table lock.*/
static inline unsigned int nr_status_frames(struct grant_table *gt)
{
- return gt->nr_status_frames;
+ return atomic_read(>->nr_status_frames);
}
#define GRANT_STATUS_PER_PAGE (PAGE_SIZE / sizeof(grant_status_t))
--
1.7.10.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |