From 447e175bade9a36a638b8aa0a950aa0fb855623a Mon Sep 17 00:00:00 2001 From: Andres Lagar-Cavilla Date: Thu, 26 Jan 2012 12:46:26 +0000 Subject: Update memshr API and tools This patch is the folded version of API updates, along with the associated tool changes to ensure that the build is always consistent. API updates: - The source domain in the sharing calls is no longer assumed to be dom0. - Previously, the mem sharing code would return an opaque handle to index shared pages (and nominees) in its global hash table. By removing the hash table, the handle becomes a version, to avoid sharing a stale version of a page. Thus, libxc wrappers and tools need to be updated to recall the share functions with the information needed to fetch the page (which they readily have). Tool updates: The only (in-tree, that we know of) consumer of the mem sharing API is the memshr tool. This is updated to use the new API. Signed-off-by: Andres Lagar-Cavilla Signed-off-by: Adin Scannell Acked-by: Ian Campbell Committed-by: Tim Deegan --- tools/memshr/bidir-daemon.c | 34 ++++++++++++++++++++++++---------- tools/memshr/bidir-hash.h | 12 +++++++----- tools/memshr/interface.c | 30 ++++++++++++++++++------------ tools/memshr/memshr.h | 11 +++++++++-- 4 files changed, 58 insertions(+), 29 deletions(-) (limited to 'tools/memshr') diff --git a/tools/memshr/bidir-daemon.c b/tools/memshr/bidir-daemon.c index a7cb3c1534..a601837650 100644 --- a/tools/memshr/bidir-daemon.c +++ b/tools/memshr/bidir-daemon.c @@ -19,16 +19,25 @@ #include #include #include +#include #include "bidir-hash.h" #include "memshr-priv.h" static struct blockshr_hash *blks_hash; +/* Callback in the iterator, remember this value, and leave */ +int find_one(vbdblk_t k, share_tuple_t v, void *priv) +{ + share_tuple_t *rv = (share_tuple_t *) priv; + *rv = v; + /* Break out of iterator loop */ + return 1; +} + void* bidir_daemon(void *unused) { uint32_t nr_ent, max_nr_ent, tab_size, max_load, min_load; - static uint64_t shrhnd = 1; while(1) { @@ -41,20 +50,30 @@ void* bidir_daemon(void *unused) /* Remove some hints as soon as we get to 90% capacity */ if(10 * nr_ent > 9 * max_nr_ent) { - uint64_t next_remove = shrhnd; + share_tuple_t next_remove; int to_remove; int ret; to_remove = 0.1 * max_nr_ent; while(to_remove > 0) { - ret = blockshr_shrhnd_remove(blks_hash, next_remove, NULL); - if(ret < 0) + /* We use the iterator to get one entry */ + next_remove.handle = 0; + ret = blockshr_hash_iterator(blks_hash, find_one, &next_remove); + + if ( !ret ) + if ( next_remove.handle == 0 ) + ret = -ESRCH; + + if ( !ret ) + ret = blockshr_shrhnd_remove(blks_hash, next_remove, NULL); + + if(ret <= 0) { /* We failed to remove an entry, because of a serious hash * table error */ DPRINTF("Could not remove handle %"PRId64", error: %d\n", - next_remove, ret); + next_remove.handle, ret); /* Force to exit the loop early */ to_remove = 0; } else @@ -62,12 +81,7 @@ void* bidir_daemon(void *unused) { /* Managed to remove the entry. Note next_remove not * incremented, in case there are duplicates */ - shrhnd = next_remove; to_remove--; - } else - { - /* Failed to remove, because there is no such handle */ - next_remove++; } } } diff --git a/tools/memshr/bidir-hash.h b/tools/memshr/bidir-hash.h index 5c4acae3e0..cc9166fa47 100644 --- a/tools/memshr/bidir-hash.h +++ b/tools/memshr/bidir-hash.h @@ -20,6 +20,7 @@ #define __BIDIR_HASH_H__ #include +#include #include "memshr-priv.h" typedef struct vbdblk { @@ -81,15 +82,16 @@ static int fgprtshr_mfn_cmp(uint32_t m1, uint32_t m2) #undef BIDIR_VALUE #undef BIDIR_KEY_T #undef BIDIR_VALUE_T + /* TODO better hashes! */ static inline uint32_t blockshr_block_hash(vbdblk_t block) { return (uint32_t)(block.sec) ^ (uint32_t)(block.disk_id); } -static inline uint32_t blockshr_shrhnd_hash(uint64_t shrhnd) +static inline uint32_t blockshr_shrhnd_hash(share_tuple_t shrhnd) { - return (uint32_t)shrhnd; + return ((uint32_t) shrhnd.handle); } static inline int blockshr_block_cmp(vbdblk_t b1, vbdblk_t b2) @@ -97,15 +99,15 @@ static inline int blockshr_block_cmp(vbdblk_t b1, vbdblk_t b2) return (b1.sec == b2.sec) && (b1.disk_id == b2.disk_id); } -static inline int blockshr_shrhnd_cmp(uint64_t h1, uint64_t h2) +static inline int blockshr_shrhnd_cmp(share_tuple_t h1, share_tuple_t h2) { - return (h1 == h2); + return ( !memcmp(&h1, &h2, sizeof(share_tuple_t)) ); } #define BIDIR_NAME_PREFIX blockshr #define BIDIR_KEY block #define BIDIR_VALUE shrhnd #define BIDIR_KEY_T vbdblk_t -#define BIDIR_VALUE_T uint64_t +#define BIDIR_VALUE_T share_tuple_t #include "bidir-namedefs.h" #endif /* BLOCK_MAP */ diff --git a/tools/memshr/interface.c b/tools/memshr/interface.c index 91cf7c6c1a..b4d6d4e190 100644 --- a/tools/memshr/interface.c +++ b/tools/memshr/interface.c @@ -145,16 +145,17 @@ void memshr_vbd_image_put(uint16_t memshr_id) int memshr_vbd_issue_ro_request(char *buf, grant_ref_t gref, - uint16_t file_id, + uint16_t file_id, uint64_t sec, int secs, - uint64_t *hnd) + share_tuple_t *hnd) { vbdblk_t blk; - uint64_t s_hnd, c_hnd; + share_tuple_t source_st, client_st; + uint64_t c_hnd; int ret; - *hnd = 0; + *hnd = (share_tuple_t){ 0, 0, 0 }; if(!vbd_info.enabled) return -1; @@ -169,26 +170,31 @@ int memshr_vbd_issue_ro_request(char *buf, /* If page couldn't be made sharable, we cannot do anything about it */ if(ret != 0) return -3; - *hnd = c_hnd; + + client_st = (share_tuple_t){ vbd_info.domid, gref, c_hnd }; + *hnd = client_st; /* Check if we've read matching disk block previously */ blk.sec = sec; blk.disk_id = file_id; - if(blockshr_block_lookup(memshr.blks, blk, &s_hnd) > 0) + if(blockshr_block_lookup(memshr.blks, blk, &source_st) > 0) { - ret = xc_memshr_share(vbd_info.xc_handle, s_hnd, c_hnd); + ret = xc_memshr_share_grefs(vbd_info.xc_handle, source_st.domain, source_st.frame, + source_st.handle, vbd_info.domid, gref, c_hnd); if(!ret) return 0; /* Handles failed to be shared => at least one of them must be invalid, remove the relevant ones from the map */ switch(ret) { case XEN_DOMCTL_MEM_SHARING_S_HANDLE_INVALID: - ret = blockshr_shrhnd_remove(memshr.blks, s_hnd, NULL); - if(ret) DPRINTF("Could not rm invl s_hnd: %"PRId64"\n", s_hnd); + ret = blockshr_shrhnd_remove(memshr.blks, source_st, NULL); + if(ret) DPRINTF("Could not rm invl s_hnd: %u %"PRId64" %"PRId64"\n", + source_st.domain, source_st.frame, source_st.handle); break; case XEN_DOMCTL_MEM_SHARING_C_HANDLE_INVALID: - ret = blockshr_shrhnd_remove(memshr.blks, c_hnd, NULL); - if(ret) DPRINTF("Could not rm invl c_hnd: %"PRId64"\n", c_hnd); + ret = blockshr_shrhnd_remove(memshr.blks, client_st, NULL); + if(ret) DPRINTF("Could not rm invl c_hnd: %u %"PRId64" %"PRId64"\n", + client_st.domain, client_st.frame, client_st.handle); break; default: break; @@ -199,7 +205,7 @@ int memshr_vbd_issue_ro_request(char *buf, return -4; } -void memshr_vbd_complete_ro_request(uint64_t hnd, +void memshr_vbd_complete_ro_request(share_tuple_t hnd, uint16_t file_id, uint64_t sec, int secs) diff --git a/tools/memshr/memshr.h b/tools/memshr/memshr.h index 24dd04c4f3..32c1d815da 100644 --- a/tools/memshr/memshr.h +++ b/tools/memshr/memshr.h @@ -25,6 +25,13 @@ typedef uint64_t xen_mfn_t; +typedef struct share_tuple +{ + uint32_t domain; + uint64_t frame; + uint64_t handle; +} share_tuple_t; + extern void memshr_set_domid(int domid); extern void memshr_daemon_initialize(void); extern void memshr_vbd_initialize(void); @@ -35,9 +42,9 @@ extern int memshr_vbd_issue_ro_request(char *buf, uint16_t file_id, uint64_t sec, int secs, - uint64_t *hnd); + share_tuple_t *hnd); extern void memshr_vbd_complete_ro_request( - uint64_t hnd, + share_tuple_t hnd, uint16_t file_id, uint64_t sec, int secs); -- cgit v1.2.3