aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_domain_save.c
diff options
context:
space:
mode:
authorOlaf Hering <olaf@aepfle.de>2011-06-10 10:47:03 +0200
committerOlaf Hering <olaf@aepfle.de>2011-06-10 10:47:03 +0200
commitaa1355f971287932e2ba09dfb04a6122ecc3951f (patch)
treeb84ec9861d1b3409fed90ebaa7e6b8d857af4a3b /tools/libxc/xc_domain_save.c
parent9c1ebbba309d04e15c8bc768843127c2c8b84c5f (diff)
downloadxen-aa1355f971287932e2ba09dfb04a6122ecc3951f.tar.gz
xen-aa1355f971287932e2ba09dfb04a6122ecc3951f.tar.bz2
xen-aa1355f971287932e2ba09dfb04a6122ecc3951f.zip
tools: merge several bitop functions into xc_bitops.h
Bitmaps are used in save/restore, xenpaging and blktap2. Merge the code into a private xc_bitops.h file. All users are single threaded, so locking is not an issue. The array of bits is handled as volatile because the x86 save/restore code passes the bitmap to the hypervisor which in turn modifies the bitmap. blktap2 uses a private bitmap. There was a possible overflow in the bitmap_size() function, the remainder was not considered. ia64 save/restore uses a bitmap to send the number of vcpus to the host. x86 save/restore uses a bitmap to track dirty pages. This bitmap is shared with the hypervisor. An unused function count_bits() was removed and a new bitmap_size() function is now used. xenpaging uses 3 private bitmaps to track the gfns which are in paged-out state. It had a copy of some Linux bitops.h, which is now obsolete. Also the BITS_PER_LONG macro was hardcoded to 64 which made it impossible to run 32bit tools on a 64bit host. Wether this works at all has to be tested, yet. Signed-off-by: Olaf Hering <olaf@aepfle.de> Committed-by: Ian Jackson <ian.jackson.citrix.com>
Diffstat (limited to 'tools/libxc/xc_domain_save.c')
-rw-r--r--tools/libxc/xc_domain_save.c66
1 files changed, 8 insertions, 58 deletions
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index aec822c6c2..5bd2d5eb12 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -27,6 +27,7 @@
#include <sys/time.h>
#include "xc_private.h"
+#include "xc_bitops.h"
#include "xc_dom.h"
#include "xg_private.h"
#include "xg_save_restore.h"
@@ -88,57 +89,6 @@ struct outbuf {
#define SUPER_PAGE_START(pfn) (((pfn) & (SUPERPAGE_NR_PFNS-1)) == 0 )
-/*
-** During (live) save/migrate, we maintain a number of bitmaps to track
-** which pages we have to send, to fixup, and to skip.
-*/
-
-#define BITS_PER_LONG (sizeof(unsigned long) * 8)
-#define BITS_TO_LONGS(bits) (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
-#define BITMAP_SIZE (BITS_TO_LONGS(dinfo->p2m_size) * sizeof(unsigned long))
-
-#define BITMAP_ENTRY(_nr,_bmap) \
- ((volatile unsigned long *)(_bmap))[(_nr)/BITS_PER_LONG]
-
-#define BITMAP_SHIFT(_nr) ((_nr) % BITS_PER_LONG)
-
-#define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6)
-
-static inline int test_bit (int nr, volatile void * addr)
-{
- return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1;
-}
-
-static inline void clear_bit (int nr, volatile void * addr)
-{
- BITMAP_ENTRY(nr, addr) &= ~(1UL << BITMAP_SHIFT(nr));
-}
-
-static inline void set_bit ( int nr, volatile void * addr)
-{
- BITMAP_ENTRY(nr, addr) |= (1UL << BITMAP_SHIFT(nr));
-}
-
-/* Returns the hamming weight (i.e. the number of bits set) in a N-bit word */
-static inline unsigned int hweight32(unsigned int w)
-{
- unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
- res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
- res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
- res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
- return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
-}
-
-static inline int count_bits ( int nr, volatile void *addr)
-{
- int i, count = 0;
- volatile unsigned long *p = (volatile unsigned long *)addr;
- /* We know that the array is padded to unsigned long. */
- for ( i = 0; i < (nr / (sizeof(unsigned long)*8)); i++, p++ )
- count += hweight32(*p);
- return count;
-}
-
static uint64_t tv_to_us(struct timeval *new)
{
return (new->tv_sec * 1000000) + new->tv_usec;
@@ -974,9 +924,9 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
sent_last_iter = dinfo->p2m_size;
/* Setup to_send / to_fix and to_skip bitmaps */
- to_send = xc_hypercall_buffer_alloc_pages(xch, to_send, NRPAGES(BITMAP_SIZE));
- to_skip = xc_hypercall_buffer_alloc_pages(xch, to_skip, NRPAGES(BITMAP_SIZE));
- to_fix = calloc(1, BITMAP_SIZE);
+ to_send = xc_hypercall_buffer_alloc_pages(xch, to_send, NRPAGES(bitmap_size(dinfo->p2m_size)));
+ to_skip = xc_hypercall_buffer_alloc_pages(xch, to_skip, NRPAGES(bitmap_size(dinfo->p2m_size)));
+ to_fix = calloc(1, bitmap_size(dinfo->p2m_size));
if ( !to_send || !to_fix || !to_skip )
{
@@ -984,7 +934,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
goto out;
}
- memset(to_send, 0xff, BITMAP_SIZE);
+ memset(to_send, 0xff, bitmap_size(dinfo->p2m_size));
if ( hvm )
{
@@ -1407,7 +1357,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( last_iter && debug )
{
int id = XC_SAVE_ID_ENABLE_VERIFY_MODE;
- memset(to_send, 0xff, BITMAP_SIZE);
+ memset(to_send, 0xff, bitmap_size(dinfo->p2m_size));
debug = 0;
DPRINTF("Entering debug resend-all mode\n");
@@ -1875,8 +1825,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
if ( ctx->live_m2p )
munmap(ctx->live_m2p, M2P_SIZE(ctx->max_mfn));
- xc_hypercall_buffer_free_pages(xch, to_send, NRPAGES(BITMAP_SIZE));
- xc_hypercall_buffer_free_pages(xch, to_skip, NRPAGES(BITMAP_SIZE));
+ xc_hypercall_buffer_free_pages(xch, to_send, NRPAGES(bitmap_size(dinfo->p2m_size)));
+ xc_hypercall_buffer_free_pages(xch, to_skip, NRPAGES(bitmap_size(dinfo->p2m_size)));
free(pfn_type);
free(pfn_batch);