mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
x86/mm: Check how many mfns are shared, in addition to how many are saved
This patch also moves the existing sharing-related memory op to the correct location, and adds logic to the audit() method that uses the new information. This patch only provides the Xen implementation of the domctls. Signed-off-by: Andres Lagar-Cavilla <andres@scannell.ca> Signed-off-by: Adin Scannell <adin@scannell.ca> Acked-by: Tim Deegan <tim@xen.org> Committed-by: Tim Deegan <tim@xen.org>
This commit is contained in:
1 parent
8ed0c27248
commit
2bc918fd8a
6 files changed
+40
-6
No files matched your search
@@ -119,7 +119,6 @@
|
||||
#include <xen/trace.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/mem_sharing.h>
|
||||
|
||||
/*
|
||||
* Mapping of first 2 or 4 megabytes of memory. This is mapped with 4kB
|
||||
@@ -5023,11 +5022,6 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
case XENMEM_get_sharing_freed_pages:
|
||||
return mem_sharing_get_nr_saved_mfns();
|
||||
#endif
|
||||
|
||||
default:
|
||||
return subarch_memory_op(op, arg);
|
||||
}
|
||||
|
||||
@@ -138,6 +138,7 @@ static inline shr_handle_t get_next_handle(void)
|
||||
#define page_to_mfn(_pg) _mfn(__page_to_mfn(_pg))
|
||||
|
||||
static atomic_t nr_saved_mfns = ATOMIC_INIT(0);
|
||||
static atomic_t nr_shared_mfns = ATOMIC_INIT(0);
|
||||
|
||||
typedef struct gfn_info
|
||||
{
|
||||
@@ -208,9 +209,12 @@ static struct page_info* mem_sharing_lookup(unsigned long mfn)
|
||||
static void mem_sharing_audit(void)
|
||||
{
|
||||
int errors = 0;
|
||||
unsigned long count_expected;
|
||||
unsigned long count_found = 0;
|
||||
struct list_head *ae;
|
||||
|
||||
ASSERT(shr_locked_by_me());
|
||||
count_expected = atomic_read(&nr_shared_mfns);
|
||||
|
||||
list_for_each(ae, &shr_audit_list)
|
||||
{
|
||||
@@ -258,6 +262,9 @@ static void mem_sharing_audit(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We've found a page that is shared */
|
||||
count_found++;
|
||||
|
||||
/* Check if all GFNs map to the MFN, and the p2m types */
|
||||
list_for_each(le, &pg->shared_info->gfns)
|
||||
{
|
||||
@@ -302,6 +309,14 @@ static void mem_sharing_audit(void)
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count_found != count_expected )
|
||||
{
|
||||
MEM_SHARING_DEBUG("Expected %ld shared mfns, found %ld.",
|
||||
count_expected, count_found);
|
||||
errors++;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -342,6 +357,11 @@ unsigned int mem_sharing_get_nr_saved_mfns(void)
|
||||
return ((unsigned int)atomic_read(&nr_saved_mfns));
|
||||
}
|
||||
|
||||
unsigned int mem_sharing_get_nr_shared_mfns(void)
|
||||
{
|
||||
return (unsigned int)atomic_read(&nr_shared_mfns);
|
||||
}
|
||||
|
||||
int mem_sharing_sharing_resume(struct domain *d)
|
||||
{
|
||||
mem_event_response_t rsp;
|
||||
@@ -663,6 +683,9 @@ int mem_sharing_nominate_page(struct domain *d,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Account for this page. */
|
||||
atomic_inc(&nr_shared_mfns);
|
||||
|
||||
/* Update m2p entry to SHARED_M2P_ENTRY */
|
||||
set_gpfn_from_mfn(mfn_x(mfn), SHARED_M2P_ENTRY);
|
||||
|
||||
@@ -786,6 +809,7 @@ int mem_sharing_share_pages(struct domain *sd, unsigned long sgfn, shr_handle_t
|
||||
put_page(cpage);
|
||||
|
||||
/* We managed to free a domain page. */
|
||||
atomic_dec(&nr_shared_mfns);
|
||||
atomic_inc(&nr_saved_mfns);
|
||||
ret = 0;
|
||||
|
||||
@@ -851,6 +875,7 @@ gfn_found:
|
||||
audit_del_list(page);
|
||||
xfree(page->shared_info);
|
||||
page->shared_info = NULL;
|
||||
atomic_dec(&nr_shared_mfns);
|
||||
}
|
||||
else
|
||||
atomic_dec(&nr_saved_mfns);
|
||||
|
||||
@@ -205,6 +205,12 @@ int compat_arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
|
||||
break;
|
||||
}
|
||||
|
||||
case XENMEM_get_sharing_freed_pages:
|
||||
return mem_sharing_get_nr_saved_mfns();
|
||||
|
||||
case XENMEM_get_sharing_shared_pages:
|
||||
return mem_sharing_get_nr_shared_mfns();
|
||||
|
||||
default:
|
||||
rc = -ENOSYS;
|
||||
break;
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <asm/msr.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/numa.h>
|
||||
#include <asm/mem_sharing.h>
|
||||
#include <public/memory.h>
|
||||
|
||||
/* Parameters for PFN/MADDR compression. */
|
||||
@@ -1093,6 +1094,12 @@ long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
|
||||
|
||||
break;
|
||||
|
||||
case XENMEM_get_sharing_freed_pages:
|
||||
return mem_sharing_get_nr_saved_mfns();
|
||||
|
||||
case XENMEM_get_sharing_shared_pages:
|
||||
return mem_sharing_get_nr_shared_mfns();
|
||||
|
||||
default:
|
||||
rc = -ENOSYS;
|
||||
break;
|
||||
|
||||
@@ -45,6 +45,7 @@ struct page_sharing_info
|
||||
(is_hvm_domain(_d) && paging_mode_hap(_d))
|
||||
|
||||
unsigned int mem_sharing_get_nr_saved_mfns(void);
|
||||
unsigned int mem_sharing_get_nr_shared_mfns(void);
|
||||
int mem_sharing_nominate_page(struct domain *d,
|
||||
unsigned long gfn,
|
||||
int expected_refcnt,
|
||||
|
||||
@@ -294,6 +294,7 @@ typedef struct xen_pod_target xen_pod_target_t;
|
||||
* The call never fails.
|
||||
*/
|
||||
#define XENMEM_get_sharing_freed_pages 18
|
||||
#define XENMEM_get_sharing_shared_pages 19
|
||||
|
||||
#endif /* __XEN_PUBLIC_MEMORY_H__ */
|
||||
|
||||
|
||||