* [PATCH 01/18] xenpaging: Fix-up xenpaging tool code.
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 02/18] xenpaging: call pageout policy function in xenpaging_evict_page Olaf Hering
` (18 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.tools_xenpaging_cleanup.patch --]
[-- Type: text/plain, Size: 1468 bytes --]
This isn't directly related to EPT checking, but does some general fix-ups
to the xenpaging code (adds some extra frees, etc.)
Already-Signed-off-by: Patrick Colp <pjcolp@cs.ubc.ca>
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/xenpaging/xenpaging.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -100,7 +100,7 @@ xenpaging_t *xenpaging_init(domid_t doma
paging->mem_event.ring_page = init_page();
if ( paging->mem_event.ring_page == NULL )
{
- ERROR("Error initialising shared page");
+ ERROR("Error initialising ring page");
goto err;
}
@@ -198,13 +198,27 @@ xenpaging_t *xenpaging_init(domid_t doma
return paging;
err:
- if ( paging->bitmap )
+ if ( paging )
+ {
+ if ( paging->mem_event.shared_page )
+ {
+ munlock(paging->mem_event.shared_page, PAGE_SIZE);
+ free(paging->mem_event.shared_page);
+ }
+
+ if ( paging->mem_event.ring_page )
+ {
+ munlock(paging->mem_event.ring_page, PAGE_SIZE);
+ free(paging->mem_event.ring_page);
+ }
+
free(paging->bitmap);
- if ( paging->platform_info )
free(paging->platform_info);
- if ( paging )
+ free(paging->domain_info);
free(paging);
+ }
+ err_iface:
return NULL;
}
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 02/18] xenpaging: call pageout policy function in xenpaging_evict_page
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
2010-10-15 14:12 ` [PATCH 01/18] xenpaging: Fix-up xenpaging tool code Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 03/18] xenpaging: fix fd leak in xenstore Olaf Hering
` (17 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.pageout_policy.patch --]
[-- Type: text/plain, Size: 865 bytes --]
Notify policy about a page that was just paged out to disk.
Up to now the code called the opposite function, which clears the
(xenpaging internal) reference bit, instead of setting it and marking
the page as gone.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
---
tools/xenpaging/xenpaging.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -358,8 +358,8 @@ int xenpaging_evict_page(xenpaging_t *pa
goto out;
}
- /* Notify policy of page being paged in */
- policy_notify_paged_in(paging->mem_event.domain_id, victim->gfn);
+ /* Notify policy of page being paged out */
+ policy_notify_paged_out(paging->mem_event.domain_id, victim->gfn);
out:
return ret;
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 03/18] xenpaging: fix fd leak in xenstore
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
2010-10-15 14:12 ` [PATCH 01/18] xenpaging: Fix-up xenpaging tool code Olaf Hering
2010-10-15 14:12 ` [PATCH 02/18] xenpaging: call pageout policy function in xenpaging_evict_page Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 04/18] xenpaging: break endless loop during inital page-out with large pagefiles Olaf Hering
` (16 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.xs_daemon_close.patch --]
[-- Type: text/plain, Size: 593 bytes --]
Missing from commit 'libxl: Backported stuff from unstable'
Without this change, xs_daemon_open/xs_daemon_close will leak filedescriptors.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/xenstore/xs.c | 2 ++
1 file changed, 2 insertions(+)
--- xen-4.0.1-testing.orig/tools/xenstore/xs.c
+++ xen-4.0.1-testing/tools/xenstore/xs.c
@@ -285,6 +285,8 @@ void xs_daemon_close(struct xs_handle *h
mutex_unlock(&h->request_mutex);
mutex_unlock(&h->reply_mutex);
mutex_unlock(&h->watch_mutex);
+
+ close_fds_free(h);
}
static bool read_all(int fd, void *data, unsigned int len)
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 04/18] xenpaging: break endless loop during inital page-out with large pagefiles
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (2 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 03/18] xenpaging: fix fd leak in xenstore Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 05/18] xenpaging: Open paging file only if xenpaging_init() succeeds Olaf Hering
` (15 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.policy_linear.patch --]
[-- Type: text/plain, Size: 3828 bytes --]
To allow the starting for xenpaging right after 'xm start XYZ', I
specified a pagefile size equal to the guest memory size in the hope to
catch more errors where the paged-out state of a p2mt is not checked.
While doing that, xenpaging got into an endless loop because some pages
cant be paged out right away. Now the policy reports an error if the gfn
number wraps.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>
---
tools/xenpaging/policy_default.c | 35 ++++++++++++++++++++++++++++-------
tools/xenpaging/xenpaging.c | 7 +++++--
2 files changed, 33 insertions(+), 9 deletions(-)
--- xen-4.0.1-testing.orig/tools/xenpaging/policy_default.c
+++ xen-4.0.1-testing/tools/xenpaging/policy_default.c
@@ -30,8 +30,12 @@
static unsigned long mru[MRU_SIZE];
-static unsigned int i_mru = 0;
+static unsigned int i_mru;
static unsigned long *bitmap;
+static unsigned long *unconsumed;
+static unsigned long current_gfn;
+static unsigned long bitmap_size;
+static unsigned long max_pages;
int policy_init(xenpaging_t *paging)
@@ -43,6 +47,14 @@ int policy_init(xenpaging_t *paging)
rc = alloc_bitmap(&bitmap, paging->bitmap_size);
if ( rc != 0 )
goto out;
+ /* Allocate bitmap to track unusable pages */
+ rc = alloc_bitmap(&unconsumed, paging->bitmap_size);
+ if ( rc != 0 )
+ goto out;
+
+ /* record bitmap_size */
+ bitmap_size = paging->bitmap_size;
+ max_pages = paging->domain_info->max_pages;
/* Initialise MRU list of paged in pages */
for ( i = 0; i < MRU_SIZE; i++ )
@@ -51,8 +63,6 @@ int policy_init(xenpaging_t *paging)
/* Don't page out page 0 */
set_bit(0, bitmap);
- rc = 0;
-
out:
return rc;
}
@@ -60,17 +70,27 @@ int policy_init(xenpaging_t *paging)
int policy_choose_victim(xenpaging_t *paging, domid_t domain_id,
xenpaging_victim_t *victim)
{
+ unsigned long wrap = current_gfn;
ASSERT(victim != NULL);
/* Domain to pick on */
victim->domain_id = domain_id;
-
+
do
{
- /* Randomly choose a gfn to evict */
- victim->gfn = rand() % paging->domain_info->max_pages;
+ current_gfn++;
+ if ( current_gfn >= max_pages )
+ current_gfn = 0;
+ if ( wrap == current_gfn )
+ {
+ victim->gfn = INVALID_MFN;
+ return -ENOSPC;
+ }
}
- while ( test_bit(victim->gfn, bitmap) );
+ while ( test_bit(current_gfn, bitmap) || test_bit(current_gfn, unconsumed) );
+
+ set_bit(current_gfn, unconsumed);
+ victim->gfn = current_gfn;
return 0;
}
@@ -78,6 +98,7 @@ int policy_choose_victim(xenpaging_t *pa
void policy_notify_paged_out(domid_t domain_id, unsigned long gfn)
{
set_bit(gfn, bitmap);
+ clear_bit(gfn, unconsumed);
}
void policy_notify_paged_in(domid_t domain_id, unsigned long gfn)
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -440,7 +440,8 @@ static int evict_victim(xenpaging_t *pag
ret = policy_choose_victim(paging, domain_id, victim);
if ( ret != 0 )
{
- ERROR("Error choosing victim");
+ if ( ret != -ENOSPC )
+ ERROR("Error choosing victim");
goto out;
}
@@ -518,7 +519,9 @@ int main(int argc, char *argv[])
memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
for ( i = 0; i < num_pages; i++ )
{
- evict_victim(paging, domain_id, &victims[i], fd, i);
+ rc = evict_victim(paging, domain_id, &victims[i], fd, i);
+ if ( rc == -ENOSPC )
+ break;
if ( i % 100 == 0 )
DPRINTF("%d pages evicted\n", i);
}
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 05/18] xenpaging: Open paging file only if xenpaging_init() succeeds
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (3 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 04/18] xenpaging: break endless loop during inital page-out with large pagefiles Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest Olaf Hering
` (14 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.pagefile.patch --]
[-- Type: text/plain, Size: 1392 bytes --]
Open paging file only if xenpaging_init() succeeds. It can fail if the host
does not support the required virtualization features such as EPT or if
xenpaging was already started for this domain_id.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>
---
tools/xenpaging/xenpaging.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -495,15 +495,6 @@ int main(int argc, char *argv[])
victims = calloc(num_pages, sizeof(xenpaging_victim_t));
- /* Open file */
- sprintf(filename, "page_cache_%d", domain_id);
- fd = open(filename, open_flags, open_mode);
- if ( fd < 0 )
- {
- perror("failed to open file");
- return -1;
- }
-
/* Seed random-number generator */
srand(time(NULL));
@@ -515,6 +506,15 @@ int main(int argc, char *argv[])
goto out;
}
+ /* Open file */
+ sprintf(filename, "page_cache_%d", domain_id);
+ fd = open(filename, open_flags, open_mode);
+ if ( fd < 0 )
+ {
+ perror("failed to open file");
+ return -1;
+ }
+
/* Evict pages */
memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
for ( i = 0; i < num_pages; i++ )
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (4 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 05/18] xenpaging: Open paging file only if xenpaging_init() succeeds Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-18 16:54 ` Ian Jackson
2010-10-15 14:12 ` [PATCH 07/18] xenpaging/qemu-dm: add command to flush buffer cache Olaf Hering
` (13 subsequent siblings)
19 siblings, 1 reply; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.xenpaging_init.patch --]
[-- Type: text/plain, Size: 1760 bytes --]
Make sure only one xenpaging binary is active per domain.
Print info when the host lacks the required features for xenpaging.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>
---
tools/xenpaging/xenpaging.c | 12 +++++++++++-
xen/arch/x86/mm/mem_event.c | 7 +++++++
2 files changed, 18 insertions(+), 1 deletion(-)
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -119,7 +119,17 @@ xenpaging_t *xenpaging_init(domid_t doma
paging->mem_event.ring_page);
if ( rc != 0 )
{
- ERROR("Error initialising shared page");
+ switch ( errno ) {
+ case EBUSY:
+ ERROR("xenpaging is (or was) active on this domain");
+ break;
+ case ENODEV:
+ ERROR("EPT not supported for this guest");
+ break;
+ default:
+ ERROR("Error initialising shared page");
+ break;
+ }
goto err;
}
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/mem_event.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/mem_event.c
@@ -226,6 +226,13 @@ int mem_event_domctl(struct domain *d, x
mfn_t ring_mfn;
mfn_t shared_mfn;
+ /* Only one xenpaging at a time. If xenpaging crashed,
+ * the cache is in an undefined state and so is the guest
+ */
+ rc = -EBUSY;
+ if ( d->mem_event.enabled )
+ break;
+
/* Currently only EPT is supported */
rc = -ENODEV;
if ( !(is_hvm_domain(d) && d->arch.hvm_domain.hap_enabled &&
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest
2010-10-15 14:12 ` [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest Olaf Hering
@ 2010-10-18 16:54 ` Ian Jackson
2010-10-18 17:04 ` Olaf Hering
0 siblings, 1 reply; 31+ messages in thread
From: Ian Jackson @ 2010-10-18 16:54 UTC (permalink / raw)
To: Olaf Hering; +Cc: xen-devel
Olaf Hering writes ("[Xen-devel] [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest"):
> - ERROR("Error initialising shared page");
> + switch ( errno ) {
> + case EBUSY:
> + ERROR("xenpaging is (or was) active on this domain");
> + break;
> + case ENODEV:
> + ERROR("EPT not supported for this guest");
> + break;
> + default:
> + ERROR("Error initialising shared page");
> + break;
Surely this should print the actual errno value.
> + /* Only one xenpaging at a time. If xenpaging crashed,
> + * the cache is in an undefined state and so is the guest
> + */
> + rc = -EBUSY;
> + if ( d->mem_event.enabled )
> + break;
Is there any way to recover from this or is the guest just hosed ?
Ian.
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest
2010-10-18 16:54 ` Ian Jackson
@ 2010-10-18 17:04 ` Olaf Hering
2010-10-19 10:17 ` Ian Jackson
0 siblings, 1 reply; 31+ messages in thread
From: Olaf Hering @ 2010-10-18 17:04 UTC (permalink / raw)
To: Ian Jackson; +Cc: xen-devel
On Mon, Oct 18, Ian Jackson wrote:
> Olaf Hering writes ("[Xen-devel] [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest"):
> > - ERROR("Error initialising shared page");
> > + switch ( errno ) {
> > + case EBUSY:
> > + ERROR("xenpaging is (or was) active on this domain");
> > + break;
> > + case ENODEV:
> > + ERROR("EPT not supported for this guest");
> > + break;
> > + default:
> > + ERROR("Error initialising shared page");
> > + break;
>
> Surely this should print the actual errno value.
Ok, can be done.
> > + /* Only one xenpaging at a time. If xenpaging crashed,
> > + * the cache is in an undefined state and so is the guest
> > + */
> > + rc = -EBUSY;
> > + if ( d->mem_event.enabled )
> > + break;
>
> Is there any way to recover from this or is the guest just hosed ?
If xenpaging dies for some reason, the bitmap which maps the "pageslot"
in the pagefile to the gfn in the guest is gone. There is no way to
recover from this situation. If the paging state should be persistant,
then the maintained bitmaps have to be kept in memory and each page write
has to be fsynced in some way.
Some other way has to be found to prevent two xenpaging runs per
domain_id.
Olaf
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest
2010-10-18 17:04 ` Olaf Hering
@ 2010-10-19 10:17 ` Ian Jackson
0 siblings, 0 replies; 31+ messages in thread
From: Ian Jackson @ 2010-10-19 10:17 UTC (permalink / raw)
To: Olaf Hering; +Cc: xen-devel@lists.xensource.com
Olaf Hering writes ("Re: [Xen-devel] [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest"):
> On Mon, Oct 18, Ian Jackson wrote:
> > Is there any way to recover from this or is the guest just hosed ?
>
> If xenpaging dies for some reason, the bitmap which maps the "pageslot"
> in the pagefile to the gfn in the guest is gone. There is no way to
> recover from this situation. If the paging state should be persistant,
> then the maintained bitmaps have to be kept in memory and each page write
> has to be fsynced in some way.
> Some other way has to be found to prevent two xenpaging runs per
> domain_id.
OK, I just thought I'd ask.
Ian.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 07/18] xenpaging/qemu-dm: add command to flush buffer cache.
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (5 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 08/18] xenpaging: handle paged-out pages in XENMEM_* commands Olaf Hering
` (12 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.mem_paging_tool_qemu_flush_cache.patch --]
[-- Type: text/plain, Size: 1071 bytes --]
Add support for a xenstore dm command to flush qemu's buffer cache.
qemu will just keep mapping pages and not release them, which causes problems
for the memory pager (since the page is mapped, it won't get paged out). When
the pager has trouble finding a page to page out, it asks qemu to flush its
buffer, which releases all the page mappings. This makes it possible to find
pages to swap out agian.
Already-Signed-off-by: Patrick Colp <Patrick.Colp@citrix.com>
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/ioemu-remote/xenstore.c | 3 +++
1 file changed, 3 insertions(+)
--- xen-4.0.1-testing.orig/tools/ioemu-remote/xenstore.c
+++ xen-4.0.1-testing/tools/ioemu-remote/xenstore.c
@@ -1021,6 +1021,9 @@ static void xenstore_process_dm_command_
do_pci_add(par);
free(par);
#endif
+ } else if (!strncmp(command, "flush-cache", len)) {
+ fprintf(logfile, "dm-command: flush caches\n");
+ qemu_invalidate_map_cache();
} else {
fprintf(logfile, "dm-command: unknown command\"%*s\"\n", len, command);
}
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 08/18] xenpaging: handle paged-out pages in XENMEM_* commands
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (6 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 07/18] xenpaging/qemu-dm: add command to flush buffer cache Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 09/18] xenpaging: populate only paged-out pages Olaf Hering
` (11 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.memory_op.patch --]
[-- Type: text/plain, Size: 15538 bytes --]
Fix these two warings:
(XEN) Assertion '__mfn_valid(mfn_x(omfn))' failed at p2m.c:2200
(XEN) memory.c:171:d1 Domain 1 page number 37ff0 invalid
Handle paged-out pages in xc_memory_op, guest_physmap_add_entry and
guest_remove_page. Use new do_xenmem_op_retry helper function.
In addition, export also xen/errno.h to hvmloader to get ENOENT define.
XENMEM_populate_physmap
populate_physmap
-> guest_physmap_add_entry
XENMEM_exchange
memory_exchange
-> guest_physmap_add_entry
XENMEM_add_to_physmap
guest_physmap_add_page
-> guest_physmap_add_entry
__gnttab_map_grant_ref
create_grant_host_mapping
create_grant_p2m_mapping
-> guest_physmap_add_entry
XENMEM_decrease_reservation
decrease_reservation
-> guest_remove_page
XENMEM_add_to_physmap
-> guest_remove_page
XENMEM_add_to_physmap
-> XENMAPSPACE_gmfn
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/firmware/hvmloader/hvmloader.c | 9 +++-
tools/firmware/hvmloader/util.c | 26 +++++++++++-
tools/include/Makefile | 1
tools/ioemu-remote/hw/vga.c | 5 +-
tools/libxc/xc_domain.c | 71 +++++++++++++++++++++--------------
xen/arch/x86/mm.c | 26 ++++++++++--
xen/arch/x86/mm/p2m.c | 7 +++
xen/common/memory.c | 25 +++++++++++-
8 files changed, 131 insertions(+), 39 deletions(-)
--- xen-4.0.1-testing.orig/tools/firmware/hvmloader/hvmloader.c
+++ xen-4.0.1-testing/tools/firmware/hvmloader/hvmloader.c
@@ -29,6 +29,7 @@
#include "pci_regs.h"
#include "e820.h"
#include "option_rom.h"
+#include <xen/errno.h>
#include <xen/version.h>
#include <xen/hvm/params.h>
#include <xen/memory.h>
@@ -306,13 +307,19 @@ static void pci_setup(void)
while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend )
{
struct xen_add_to_physmap xatp;
+ int rc;
if ( hvm_info->high_mem_pgend == 0 )
hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT);
xatp.domid = DOMID_SELF;
xatp.space = XENMAPSPACE_gmfn;
xatp.idx = --hvm_info->low_mem_pgend;
xatp.gpfn = hvm_info->high_mem_pgend++;
- if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
+ do {
+ rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+ if ( rc == -ENOENT )
+ cpu_relax();
+ } while ( rc == -ENOENT );
+ if ( rc != 0 )
BUG();
}
--- xen-4.0.1-testing.orig/tools/firmware/hvmloader/util.c
+++ xen-4.0.1-testing/tools/firmware/hvmloader/util.c
@@ -23,6 +23,7 @@
#include "e820.h"
#include "hypercall.h"
#include <stdint.h>
+#include <xen/errno.h>
#include <xen/xen.h>
#include <xen/memory.h>
@@ -323,19 +324,27 @@ void *mem_alloc(uint32_t size, uint32_t
while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) )
{
+ int rc;
reserve += PAGE_SIZE;
mfn = reserve >> PAGE_SHIFT;
/* Try to allocate a brand new page in the reserved area. */
if ( !over_allocated )
{
+ uint8_t delay = 0;
xmr.domid = DOMID_SELF;
xmr.mem_flags = 0;
xmr.extent_order = 0;
xmr.nr_extents = 1;
set_xen_guest_handle(xmr.extent_start, &mfn);
- if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1 )
+ do {
+ rc = hypercall_memory_op(XENMEM_populate_physmap, &xmr);
+ if ( rc == 0 )
+ cpu_relax();
+ } while ( rc == 0 && ++delay );
+ if ( rc == 1 )
continue;
+ printf("%s: over_allocated\n", __func__);
over_allocated = 1;
}
@@ -353,7 +362,12 @@ void *mem_alloc(uint32_t size, uint32_t
xatp.domid = DOMID_SELF;
xatp.space = XENMAPSPACE_gmfn;
xatp.gpfn = mfn;
- if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
+ do {
+ rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+ if ( rc == -ENOENT )
+ cpu_relax();
+ } while ( rc == -ENOENT );
+ if ( rc != 0 )
BUG();
}
@@ -595,6 +609,7 @@ uint16_t get_cpu_mhz(void)
uint64_t cpu_khz;
uint32_t tsc_to_nsec_mul, version;
int8_t tsc_shift;
+ int rc;
static uint16_t cpu_mhz;
if ( cpu_mhz != 0 )
@@ -605,7 +620,12 @@ uint16_t get_cpu_mhz(void)
xatp.space = XENMAPSPACE_shared_info;
xatp.idx = 0;
xatp.gpfn = (unsigned long)shared_info >> 12;
- if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
+ do {
+ rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+ if ( rc == -ENOENT )
+ cpu_relax();
+ } while ( rc == -ENOENT );
+ if ( rc != 0 )
BUG();
/* Get a consistent snapshot of scale factor (multiplier and shift). */
--- xen-4.0.1-testing.orig/tools/include/Makefile
+++ xen-4.0.1-testing/tools/include/Makefile
@@ -12,6 +12,7 @@ xen/.dir:
@rm -rf xen
mkdir -p xen/libelf
ln -sf ../$(XEN_ROOT)/xen/include/public/COPYING xen
+ ln -sf ../$(XEN_ROOT)/xen/include/xen/errno.h xen
ln -sf $(addprefix ../,$(wildcard $(XEN_ROOT)/xen/include/public/*.h)) xen
ln -sf $(addprefix ../$(XEN_ROOT)/xen/include/public/,arch-ia64 arch-x86 hvm io xsm) xen
ln -sf ../xen-sys/$(XEN_OS) xen/sys
--- xen-4.0.1-testing.orig/tools/ioemu-remote/hw/vga.c
+++ xen-4.0.1-testing/tools/ioemu-remote/hw/vga.c
@@ -2157,9 +2157,10 @@ void set_vram_mapping(void *opaque, unsi
for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) {
xatp.idx = (s->vram_gmfn >> TARGET_PAGE_BITS) + i;
xatp.gpfn = (begin >> TARGET_PAGE_BITS) + i;
- rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
+ while ((rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp)) && errno == ENOENT)
+ usleep(1000);
if (rc) {
- fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"PRI_xen_pfn" failed: %d\n", xatp.idx, xatp.gpfn, rc);
+ fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"PRI_xen_pfn" failed: %d\n", xatp.idx, xatp.gpfn, errno);
return;
}
}
--- xen-4.0.1-testing.orig/tools/libxc/xc_domain.c
+++ xen-4.0.1-testing/tools/libxc/xc_domain.c
@@ -536,6 +536,44 @@ int xc_domain_get_tsc_info(int xc_handle
return rc;
}
+static int do_xenmem_op_retry(int xc_handle, int cmd, struct xen_memory_reservation *reservation, unsigned long nr_extents, xen_pfn_t *extent_start)
+{
+ int err = 0;
+ unsigned long count = nr_extents;
+ unsigned long delay = 0;
+ unsigned long start = 0;
+
+ fprintf(stderr, "%s: cmd %d count %lx\n",__func__,cmd,count);
+ while ( count && start < nr_extents )
+ {
+ set_xen_guest_handle(reservation->extent_start, extent_start + start);
+ reservation->nr_extents = count;
+
+ err = xc_memory_op(xc_handle, cmd, reservation);
+ if ( err == count )
+ {
+ err = 0;
+ break;
+ }
+
+ if ( err > count || err < 0 || delay > 1000 * 1000)
+ {
+ fprintf(stderr, "%s: %d err %x count %lx start %lx delay %lu/%lu\n",__func__,cmd,err,count,start,delay,delay/666);
+ err = -1;
+ break;
+ }
+
+ if ( err )
+ delay = 0;
+
+ start += err;
+ count -= err;
+ usleep(delay);
+ delay += 666; /* 1500 iterations, 12 seconds */
+ }
+
+ return err;
+}
int xc_domain_memory_increase_reservation(int xc_handle,
uint32_t domid,
@@ -546,26 +584,18 @@ int xc_domain_memory_increase_reservatio
{
int err;
struct xen_memory_reservation reservation = {
- .nr_extents = nr_extents,
.extent_order = extent_order,
.mem_flags = mem_flags,
.domid = domid
};
- /* may be NULL */
- set_xen_guest_handle(reservation.extent_start, extent_start);
-
- err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
- if ( err == nr_extents )
- return 0;
-
- if ( err >= 0 )
+ err = do_xenmem_op_retry(xc_handle, XENMEM_increase_reservation, &reservation, nr_extents, extent_start);
+ if ( err < 0 )
{
DPRINTF("Failed allocation for dom %d: "
"%ld extents of order %d, mem_flags %x\n",
domid, nr_extents, extent_order, mem_flags);
errno = ENOMEM;
- err = -1;
}
return err;
@@ -579,14 +609,11 @@ int xc_domain_memory_decrease_reservatio
{
int err;
struct xen_memory_reservation reservation = {
- .nr_extents = nr_extents,
.extent_order = extent_order,
.mem_flags = 0,
.domid = domid
};
- set_xen_guest_handle(reservation.extent_start, extent_start);
-
if ( extent_start == NULL )
{
DPRINTF("decrease_reservation extent_start is NULL!\n");
@@ -594,16 +621,12 @@ int xc_domain_memory_decrease_reservatio
return -1;
}
- err = xc_memory_op(xc_handle, XENMEM_decrease_reservation, &reservation);
- if ( err == nr_extents )
- return 0;
-
- if ( err >= 0 )
+ err = do_xenmem_op_retry(xc_handle, XENMEM_decrease_reservation, &reservation, nr_extents, extent_start);
+ if ( err < 0 )
{
DPRINTF("Failed deallocation for dom %d: %ld extents of order %d\n",
domid, nr_extents, extent_order);
errno = EINVAL;
- err = -1;
}
return err;
@@ -618,23 +641,17 @@ int xc_domain_memory_populate_physmap(in
{
int err;
struct xen_memory_reservation reservation = {
- .nr_extents = nr_extents,
.extent_order = extent_order,
.mem_flags = mem_flags,
.domid = domid
};
- set_xen_guest_handle(reservation.extent_start, extent_start);
-
- err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
- if ( err == nr_extents )
- return 0;
- if ( err >= 0 )
+ err = do_xenmem_op_retry(xc_handle, XENMEM_populate_physmap, &reservation, nr_extents, extent_start);
+ if ( err < 0 )
{
DPRINTF("Failed allocation for dom %d: %ld extents of order %d\n",
domid, nr_extents, extent_order);
errno = EBUSY;
- err = -1;
}
return err;
--- xen-4.0.1-testing.orig/xen/arch/x86/mm.c
+++ xen-4.0.1-testing/xen/arch/x86/mm.c
@@ -3660,6 +3660,8 @@ static int create_grant_p2m_mapping(uint
p2mt = p2m_grant_map_rw;
rc = guest_physmap_add_entry(current->domain, addr >> PAGE_SHIFT,
frame, 0, p2mt);
+ if ( rc == -ENOENT )
+ return GNTST_eagain;
if ( rc )
return GNTST_general_error;
else
@@ -4315,17 +4317,25 @@ long arch_memory_op(int op, XEN_GUEST_HA
case XENMAPSPACE_gmfn:
{
p2m_type_t p2mt;
+ unsigned long tmp_mfn;
- xatp.idx = mfn_x(gfn_to_mfn_unshare(d, xatp.idx, &p2mt, 0));
+ tmp_mfn = mfn_x(gfn_to_mfn_unshare(d, xatp.idx, &p2mt, 0));
+ if ( unlikely(p2m_is_paging(p2mt)) )
+ {
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(d, xatp.idx);
+ rcu_unlock_domain(d);
+ return -ENOENT;
+ }
/* If the page is still shared, exit early */
if ( p2m_is_shared(p2mt) )
{
rcu_unlock_domain(d);
return -ENOMEM;
}
- if ( !get_page_from_pagenr(xatp.idx, d) )
+ if ( !get_page_from_pagenr(tmp_mfn, d) )
break;
- mfn = xatp.idx;
+ mfn = tmp_mfn;
page = mfn_to_page(mfn);
break;
}
@@ -4354,8 +4364,16 @@ long arch_memory_op(int op, XEN_GUEST_HA
/* Xen heap frames are simply unhooked from this phys slot. */
guest_physmap_remove_page(d, xatp.gpfn, prev_mfn, 0);
else
+ {
/* Normal domain memory is freed, to avoid leaking memory. */
- guest_remove_page(d, xatp.gpfn);
+ rc = guest_remove_page(d, xatp.gpfn);
+ if ( rc == -ENOENT )
+ {
+ domain_unlock(d);
+ rcu_unlock_domain(d);
+ return rc;
+ }
+ }
}
/* Unmap from old location, if any. */
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c
@@ -2186,6 +2186,13 @@ guest_physmap_add_entry(struct domain *d
P2M_DEBUG("aliased! mfn=%#lx, old gfn=%#lx, new gfn=%#lx\n",
mfn + i, ogfn, gfn + i);
omfn = gfn_to_mfn_query(d, ogfn, &ot);
+ if ( unlikely(p2m_is_paging(ot)) )
+ {
+ p2m_unlock(d->arch.p2m);
+ if ( p2m_is_paged(ot) )
+ p2m_mem_paging_populate(d, ogfn);
+ return -ENOENT;
+ }
/* If we get here, we know the local domain owns the page,
so it can't have been grant mapped in. */
BUG_ON( p2m_is_grant(ot) );
--- xen-4.0.1-testing.orig/xen/common/memory.c
+++ xen-4.0.1-testing/xen/common/memory.c
@@ -95,6 +95,7 @@ static void populate_physmap(struct memo
unsigned long i, j;
xen_pfn_t gpfn, mfn;
struct domain *d = a->domain;
+ int rc;
if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done,
a->nr_extents-1) )
@@ -134,7 +135,12 @@ static void populate_physmap(struct memo
}
mfn = page_to_mfn(page);
- guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
+ rc = guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
+ if ( rc != 0 )
+ {
+ free_domheap_pages(page, a->extent_order);
+ goto out;
+ }
if ( !paging_mode_translate(d) )
{
@@ -162,6 +168,12 @@ int guest_remove_page(struct domain *d,
#ifdef CONFIG_X86
mfn = mfn_x(gfn_to_mfn(d, gmfn, &p2mt));
+ if ( unlikely(p2m_is_paging(p2mt)) )
+ {
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(d, gmfn);
+ return -ENOENT;
+ }
#else
mfn = gmfn_to_mfn(d, gmfn);
#endif
@@ -360,6 +372,13 @@ static long memory_exchange(XEN_GUEST_HA
/* Shared pages cannot be exchanged */
mfn = mfn_x(gfn_to_mfn_unshare(d, gmfn + k, &p2mt, 0));
+ if ( p2m_is_paging(p2mt) )
+ {
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(d, gmfn);
+ rc = -ENOENT;
+ goto fail;
+ }
if ( p2m_is_shared(p2mt) )
{
rc = -ENOMEM;
@@ -456,7 +475,9 @@ static long memory_exchange(XEN_GUEST_HA
&gpfn, exch.out.extent_start, (i<<out_chunk_order)+j, 1);
mfn = page_to_mfn(page);
- guest_physmap_add_page(d, gpfn, mfn, exch.out.extent_order);
+ rc = guest_physmap_add_page(d, gpfn, mfn, exch.out.extent_order);
+ if ( rc == -ENOENT )
+ goto fail;
if ( !paging_mode_translate(d) )
{
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 09/18] xenpaging: populate only paged-out pages
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (7 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 08/18] xenpaging: handle paged-out pages in XENMEM_* commands Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 10/18] xenpaging: reduce MINIMUM_RESTART_TIME Olaf Hering
` (10 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.populate_only_if_paged.patch --]
[-- Type: text/plain, Size: 4239 bytes --]
populdate a paged-out page only once to reduce pressure in the ringbuffer.
Several cpus may still request a page at once. xenpaging can handle this.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
xen/arch/x86/hvm/emulate.c | 3 ++-
xen/arch/x86/hvm/hvm.c | 17 ++++++++++-------
xen/arch/x86/mm/guest_walk.c | 3 ++-
xen/arch/x86/mm/hap/guest_walk.c | 6 ++++--
4 files changed, 18 insertions(+), 11 deletions(-)
--- xen-4.0.1-testing.orig/xen/arch/x86/hvm/emulate.c
+++ xen-4.0.1-testing/xen/arch/x86/hvm/emulate.c
@@ -65,7 +65,8 @@ static int hvmemul_do_io(
ram_mfn = gfn_to_mfn_unshare(current->domain, ram_gfn, &p2mt, 0);
if ( p2m_is_paging(p2mt) )
{
- p2m_mem_paging_populate(curr->domain, ram_gfn);
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(curr->domain, ram_gfn);
return X86EMUL_RETRY;
}
if ( p2m_is_shared(p2mt) )
--- xen-4.0.1-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.0.1-testing/xen/arch/x86/hvm/hvm.c
@@ -291,7 +291,8 @@ static int hvm_set_ioreq_page(
return -EINVAL;
if ( p2m_is_paging(p2mt) )
{
- p2m_mem_paging_populate(d, gmfn);
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(d, gmfn);
return -ENOENT;
}
if ( p2m_is_shared(p2mt) )
@@ -1324,7 +1325,8 @@ static void *hvm_map_entry(unsigned long
mfn = mfn_x(gfn_to_mfn_unshare(current->domain, gfn, &p2mt, 0));
if ( p2m_is_paging(p2mt) )
{
- p2m_mem_paging_populate(current->domain, gfn);
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(current->domain, gfn);
return NULL;
}
if ( p2m_is_shared(p2mt) )
@@ -1723,7 +1725,8 @@ static enum hvm_copy_result __hvm_copy(
if ( p2m_is_paging(p2mt) )
{
- p2m_mem_paging_populate(curr->domain, gfn);
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(curr->domain, gfn);
return HVMCOPY_gfn_paged_out;
}
if ( p2m_is_shared(p2mt) )
@@ -3032,8 +3035,8 @@ long do_hvm_op(unsigned long op, XEN_GUE
mfn_t mfn = gfn_to_mfn(d, pfn, &t);
if ( p2m_is_paging(t) )
{
- p2m_mem_paging_populate(d, pfn);
-
+ if ( p2m_is_paged(t) )
+ p2m_mem_paging_populate(d, pfn);
rc = -EINVAL;
goto param_fail3;
}
@@ -3096,8 +3099,8 @@ long do_hvm_op(unsigned long op, XEN_GUE
mfn = gfn_to_mfn_unshare(d, pfn, &t, 0);
if ( p2m_is_paging(t) )
{
- p2m_mem_paging_populate(d, pfn);
-
+ if ( p2m_is_paged(t) )
+ p2m_mem_paging_populate(d, pfn);
rc = -EINVAL;
goto param_fail4;
}
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/guest_walk.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/guest_walk.c
@@ -96,7 +96,8 @@ static inline void *map_domain_gfn(struc
*mfn = gfn_to_mfn_unshare(d, gfn_x(gfn), p2mt, 0);
if ( p2m_is_paging(*p2mt) )
{
- p2m_mem_paging_populate(d, gfn_x(gfn));
+ if ( p2m_is_paged(*p2mt) )
+ p2m_mem_paging_populate(d, gfn_x(gfn));
*rc = _PAGE_PAGED;
return NULL;
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/hap/guest_walk.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/hap/guest_walk.c
@@ -49,7 +49,8 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
top_mfn = gfn_to_mfn_unshare(v->domain, cr3 >> PAGE_SHIFT, &p2mt, 0);
if ( p2m_is_paging(p2mt) )
{
- p2m_mem_paging_populate(v->domain, cr3 >> PAGE_SHIFT);
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(v->domain, cr3 >> PAGE_SHIFT);
pfec[0] = PFEC_page_paged;
return INVALID_GFN;
@@ -81,7 +82,8 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
gfn_to_mfn_unshare(v->domain, gfn_x(gfn), &p2mt, 0);
if ( p2m_is_paging(p2mt) )
{
- p2m_mem_paging_populate(v->domain, gfn_x(gfn));
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(v->domain, gfn_x(gfn));
pfec[0] = PFEC_page_paged;
return INVALID_GFN;
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 10/18] xenpaging: reduce MINIMUM_RESTART_TIME
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (8 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 09/18] xenpaging: populate only paged-out pages Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 11/18] xenpaging: start xenpaging via config option Olaf Hering
` (9 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.MINIMUM_RESTART_TIME.patch --]
[-- Type: text/plain, Size: 596 bytes --]
Allow runlevel 6 as default runlevel.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/python/xen/xend/XendConstants.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- xen-4.0.1-testing.orig/tools/python/xen/xend/XendConstants.py
+++ xen-4.0.1-testing/tools/python/xen/xend/XendConstants.py
@@ -92,7 +92,7 @@ DOM_STATES_OLD = [
SHUTDOWN_TIMEOUT = (60.0 * 5)
"""Minimum time between domain restarts in seconds."""
-MINIMUM_RESTART_TIME = 60
+MINIMUM_RESTART_TIME = 5
RESTART_IN_PROGRESS = 'xend/restart_in_progress'
DUMPCORE_IN_PROGRESS = 'xend/dumpcore_in_progress'
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 11/18] xenpaging: start xenpaging via config option
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (9 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 10/18] xenpaging: reduce MINIMUM_RESTART_TIME Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 12/18] xenpaging: add signal handling Olaf Hering
` (8 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.autostart.patch --]
[-- Type: text/plain, Size: 9324 bytes --]
Start xenpaging via config option.
TODO: add config option for pagefile directory
TODO: add libxl support
TODO: parse config values like 42K, 42M, 42G, 42%
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/examples/xmexample.hvm | 3 +
tools/python/README.XendConfig | 1
tools/python/README.sxpcfg | 1
tools/python/xen/xend/XendConfig.py | 3 +
tools/python/xen/xend/XendDomainInfo.py | 6 ++
tools/python/xen/xend/image.py | 87 ++++++++++++++++++++++++++++++++
tools/python/xen/xm/create.py | 5 +
tools/python/xen/xm/xenapi_create.py | 1
8 files changed, 107 insertions(+)
--- xen-4.0.1-testing.orig/tools/examples/xmexample.hvm
+++ xen-4.0.1-testing/tools/examples/xmexample.hvm
@@ -127,6 +127,9 @@ disk = [ 'file:/var/lib/xen/images/disk.
# Device Model to be used
device_model = 'qemu-dm'
+# xenpaging, number of pages
+xenpaging = 42
+
#-----------------------------------------------------------------------------
# boot on floppy (a), hard disk (c), Network (n) or CD-ROM (d)
# default: hard disk, cd-rom, floppy
--- xen-4.0.1-testing.orig/tools/python/README.XendConfig
+++ xen-4.0.1-testing/tools/python/README.XendConfig
@@ -120,6 +120,7 @@ otherConfig
image.vncdisplay
image.vncunused
image.hvm.device_model
+ image.hvm.xenpaging
image.hvm.display
image.hvm.xauthority
image.hvm.vncconsole
--- xen-4.0.1-testing.orig/tools/python/README.sxpcfg
+++ xen-4.0.1-testing/tools/python/README.sxpcfg
@@ -51,6 +51,7 @@ image
- vncunused
(HVM)
- device_model
+ - xenpaging
- display
- xauthority
- vncconsole
--- xen-4.0.1-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-4.0.1-testing/tools/python/xen/xend/XendConfig.py
@@ -145,6 +145,7 @@ XENAPI_PLATFORM_CFG_TYPES = {
'apic': int,
'boot': str,
'device_model': str,
+ 'xenpaging': int,
'loader': str,
'display' : str,
'fda': str,
@@ -508,6 +509,8 @@ class XendConfig(dict):
self['platform']['nomigrate'] = 0
if self.is_hvm():
+ if 'xenpaging' not in self['platform']:
+ self['platform']['xenpaging'] = None
if 'timer_mode' not in self['platform']:
self['platform']['timer_mode'] = 1
if 'viridian' not in self['platform']:
--- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -2439,6 +2439,7 @@ class XendDomainInfo:
if self.image:
self.image.createDeviceModel()
+ self.image.createXenPaging()
#if have pass-through devs, need the virtual pci slots info from qemu
self.pci_device_configure_boot()
@@ -2451,6 +2452,11 @@ class XendDomainInfo:
self.image.destroyDeviceModel()
except Exception, e:
log.exception("Device model destroy failed %s" % str(e))
+ try:
+ log.debug("stopping xenpaging")
+ self.image.destroyXenPaging()
+ except Exception, e:
+ log.exception("stopping xenpaging failed %s" % str(e))
else:
log.debug("No device model")
--- xen-4.0.1-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.0.1-testing/tools/python/xen/xend/image.py
@@ -122,12 +122,14 @@ class ImageHandler:
self.vm.permissionsVm("image/cmdline", { 'dom': self.vm.getDomid(), 'read': True } )
self.device_model = vmConfig['platform'].get('device_model')
+ self.xenpaging = vmConfig['platform'].get('xenpaging')
self.display = vmConfig['platform'].get('display')
self.xauthority = vmConfig['platform'].get('xauthority')
self.vncconsole = int(vmConfig['platform'].get('vncconsole', 0))
self.dmargs = self.parseDeviceModelArgs(vmConfig)
self.pid = None
+ self.xenpaging_pid = None
rtc_timeoffset = int(vmConfig['platform'].get('rtc_timeoffset', 0))
if int(vmConfig['platform'].get('localtime', 0)):
if time.localtime(time.time())[8]:
@@ -392,6 +394,91 @@ class ImageHandler:
sentinel_fifos_inuse[sentinel_path_fifo] = 1
self.sentinel_path_fifo = sentinel_path_fifo
+ def createXenPaging(self):
+ if self.xenpaging is None:
+ return
+ if self.xenpaging == 0:
+ return
+ if self.xenpaging_pid:
+ return
+ xenpaging_bin = auxbin.pathTo("xenpaging")
+ args = [xenpaging_bin]
+ args = args + ([ "%d" % self.vm.getDomid()])
+ args = args + ([ "%s" % self.xenpaging])
+ env = dict(os.environ)
+ self.xenpaging_logfile = "/var/log/xen/xenpaging-%s.log" % str(self.vm.info['name_label'])
+ logfile_mode = os.O_WRONLY|os.O_CREAT|os.O_APPEND|os.O_TRUNC
+ null = os.open("/dev/null", os.O_RDONLY)
+ logfd = os.open(self.xenpaging_logfile, logfile_mode, 0644)
+ sys.stderr.flush()
+ contract = osdep.prefork("%s:%d" % (self.vm.getName(), self.vm.getDomid()))
+ xenpaging_pid = os.fork()
+ if xenpaging_pid == 0: #child
+ try:
+ xenpaging_dir = "/var/lib/xen/xenpaging"
+ osdep.postfork(contract)
+ os.dup2(null, 0)
+ os.dup2(logfd, 1)
+ os.dup2(logfd, 2)
+ try:
+ os.mkdir(xenpaging_dir)
+ except:
+ log.info("mkdir %s failed" % xenpaging_dir)
+ pass
+ try:
+ os.chdir(xenpaging_dir)
+ except:
+ log.warn("chdir %s failed" % xenpaging_dir)
+ try:
+ log.info("starting %s" % args)
+ os.execve(xenpaging_bin, args, env)
+ except Exception, e:
+ print >>sys.stderr, (
+ 'failed to execute xenpaging: %s: %s' %
+ xenpaging_bin, utils.exception_string(e))
+ os._exit(126)
+ except Exception, e:
+ log.warn("staring xenpaging in %s failed" % xenpaging_dir)
+ os._exit(127)
+ else:
+ osdep.postfork(contract, abandon=True)
+ self.xenpaging_pid = xenpaging_pid
+ os.close(null)
+ os.close(logfd)
+
+ def destroyXenPaging(self):
+ if self.xenpaging is None:
+ return
+ if self.xenpaging_pid:
+ try:
+ os.kill(self.xenpaging_pid, signal.SIGHUP)
+ except OSError, exn:
+ log.exception(exn)
+ for i in xrange(100):
+ try:
+ (p, rv) = os.waitpid(self.xenpaging_pid, os.WNOHANG)
+ if p == self.xenpaging_pid:
+ break
+ except OSError:
+ # This is expected if Xend has been restarted within
+ # the life of this domain. In this case, we can kill
+ # the process, but we can't wait for it because it's
+ # not our child. We continue this loop, and after it is
+ # terminated make really sure the process is going away
+ # (SIGKILL).
+ pass
+ time.sleep(0.1)
+ else:
+ log.warning("xenpaging %d took more than 10s "
+ "to terminate: sending SIGKILL" % self.xenpaging_pid)
+ try:
+ os.kill(self.xenpaging_pid, signal.SIGKILL)
+ os.waitpid(self.xenpaging_pid, 0)
+ except OSError:
+ # This happens if the process doesn't exist.
+ pass
+ self.xenpaging_pid = None
+
def createDeviceModel(self, restore = False):
if self.device_model is None:
return
--- xen-4.0.1-testing.orig/tools/python/xen/xm/create.py
+++ xen-4.0.1-testing/tools/python/xen/xm/create.py
@@ -495,6 +495,10 @@ gopts.var('nfs_root', val="PATH",
fn=set_value, default=None,
use="Set the path of the root NFS directory.")
+gopts.var('xenpaging', val='NUM',
+ fn=set_int, default=None,
+ use="Number of pages to swap.")
+
gopts.var('device_model', val='FILE',
fn=set_value, default=None,
use="Path to device model program.")
@@ -1080,6 +1084,7 @@ def configure_hvm(config_image, vals):
args = [ 'acpi', 'apic',
'boot',
'cpuid', 'cpuid_check',
+ 'xenpaging',
'device_model', 'display',
'fda', 'fdb',
'gfx_passthru', 'guest_os_type',
--- xen-4.0.1-testing.orig/tools/python/xen/xm/xenapi_create.py
+++ xen-4.0.1-testing/tools/python/xen/xm/xenapi_create.py
@@ -1086,6 +1086,7 @@ class sxp2xml:
'acpi',
'apic',
'boot',
+ 'xenpaging',
'device_model',
'loader',
'fda',
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 12/18] xenpaging: add signal handling
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (10 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 11/18] xenpaging: start xenpaging via config option Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 13/18] xenpaging: increase recently used pages from 4MB to 64MB Olaf Hering
` (7 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.signal_handling.patch --]
[-- Type: text/plain, Size: 4131 bytes --]
Leave paging loop if xenpaging gets a signal.
Remove paging file on exit.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/xenpaging/xenpaging.c | 39 +++++++++++++++++++++++++++++++--------
1 file changed, 31 insertions(+), 8 deletions(-)
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -22,6 +22,7 @@
#include <inttypes.h>
#include <stdlib.h>
+#include <signal.h>
#include <xc_private.h>
#include <xen/mem_event.h>
@@ -40,6 +41,11 @@
#define DPRINTF(...) ((void)0)
#endif
+static int interrupted;
+static void close_handler(int sig)
+{
+ interrupted = sig;
+}
static void *init_page(void)
{
@@ -244,7 +250,6 @@ int xenpaging_teardown(xenpaging_t *pagi
if ( rc != 0 )
{
ERROR("Error tearing down domain paging in xen");
- goto err;
}
/* Unbind VIRQ */
@@ -252,7 +257,6 @@ int xenpaging_teardown(xenpaging_t *pagi
if ( rc != 0 )
{
ERROR("Error unbinding event port");
- goto err;
}
paging->mem_event.port = -1;
@@ -261,7 +265,6 @@ int xenpaging_teardown(xenpaging_t *pagi
if ( rc != 0 )
{
ERROR("Error closing event channel");
- goto err;
}
paging->mem_event.xce_handle = -1;
@@ -270,7 +273,6 @@ int xenpaging_teardown(xenpaging_t *pagi
if ( rc != 0 )
{
ERROR("Error closing connection to xen");
- goto err;
}
paging->xc_handle = -1;
@@ -375,7 +377,7 @@ int xenpaging_evict_page(xenpaging_t *pa
return ret;
}
-int xenpaging_resume_page(xenpaging_t *paging, mem_event_response_t *rsp)
+static int xenpaging_resume_page(xenpaging_t *paging, mem_event_response_t *rsp)
{
int ret;
@@ -455,6 +457,11 @@ static int evict_victim(xenpaging_t *pag
goto out;
}
+ if ( interrupted )
+ {
+ ret = -EINTR;
+ goto out;
+ }
ret = xc_mem_paging_nominate(paging->xc_handle,
paging->mem_event.domain_id, victim->gfn);
if ( ret == 0 )
@@ -479,6 +486,7 @@ static int evict_victim(xenpaging_t *pag
int main(int argc, char *argv[])
{
+ struct sigaction act;
domid_t domain_id;
int num_pages;
xenpaging_t *paging;
@@ -513,7 +521,7 @@ int main(int argc, char *argv[])
if ( paging == NULL )
{
ERROR("Error initialising paging");
- goto out;
+ return 1;
}
/* Open file */
@@ -522,9 +530,18 @@ int main(int argc, char *argv[])
if ( fd < 0 )
{
perror("failed to open file");
- return -1;
+ return 2;
}
+ /* ensure that if we get a signal, we'll do cleanup, then exit */
+ act.sa_handler = close_handler;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ sigaction(SIGHUP, &act, NULL);
+ sigaction(SIGTERM, &act, NULL);
+ sigaction(SIGINT, &act, NULL);
+ sigaction(SIGALRM, &act, NULL);
+
/* Evict pages */
memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
for ( i = 0; i < num_pages; i++ )
@@ -532,6 +549,8 @@ int main(int argc, char *argv[])
rc = evict_victim(paging, domain_id, &victims[i], fd, i);
if ( rc == -ENOSPC )
break;
+ if ( rc == -EINTR )
+ break;
if ( i % 100 == 0 )
DPRINTF("%d pages evicted\n", i);
}
@@ -539,7 +558,7 @@ int main(int argc, char *argv[])
DPRINTF("pages evicted\n");
/* Swap pages in and out */
- while ( 1 )
+ while ( !interrupted )
{
/* Wait for Xen to signal that a page needs paged in */
rc = xc_wait_for_event_or_timeout(paging->mem_event.xce_handle, 100);
@@ -630,8 +649,11 @@ int main(int argc, char *argv[])
}
}
}
+ DPRINTF("xenpaging got signal %d\n", interrupted);
out:
+ unlink(filename);
+ close(fd);
free(victims);
/* Tear down domain paging */
@@ -642,6 +664,7 @@ int main(int argc, char *argv[])
if ( rc == 0 )
rc = rc1;
+ DPRINTF("xenpaging exit code %d\n", rc);
return rc;
}
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 13/18] xenpaging: increase recently used pages from 4MB to 64MB
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (11 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 12/18] xenpaging: add signal handling Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 14/18] xenpaging: page-in granttable entries Olaf Hering
` (6 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.MRU_SIZE.patch --]
[-- Type: text/plain, Size: 559 bytes --]
Increase recently used pages from 4MB to 64MB.
Keeping more pages in memory allows the guest to make more progress if the
paging file spans the entire guest memory.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/xenpaging/policy_default.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- xen-4.0.1-testing.orig/tools/xenpaging/policy_default.c
+++ xen-4.0.1-testing/tools/xenpaging/policy_default.c
@@ -26,7 +26,7 @@
#include "policy.h"
-#define MRU_SIZE 1024
+#define MRU_SIZE (1024 * 16)
static unsigned long mru[MRU_SIZE];
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 14/18] xenpaging: page-in granttable entries
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (12 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 13/18] xenpaging: increase recently used pages from 4MB to 64MB Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 15/18] xenpaging: handle dying guest in notify_via_xen_event_channel Olaf Hering
` (5 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.get_paged_frame.patch --]
[-- Type: text/plain, Size: 5703 bytes --]
When converting a gfn to mfn, check if the page is paged-out.
If it is, request a page-in and return GNTST_eagain to the caller
to indicate a retry of the hypercall is required.
This fixes granttable errors when xenpaging is enabled in the guest.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>
---
xen/common/grant_table.c | 94 ++++++++++++++++++++++++++++++-----------------
1 file changed, 60 insertions(+), 34 deletions(-)
--- xen-4.0.1-testing.orig/xen/common/grant_table.c
+++ xen-4.0.1-testing/xen/common/grant_table.c
@@ -139,6 +139,37 @@ shared_entry_header(struct grant_table *
#define active_entry(t, e) \
((t)->active[(e)/ACGNT_PER_PAGE][(e)%ACGNT_PER_PAGE])
+/* Check if the page has been paged out */
+static int __get_paged_frame(unsigned long gfn, unsigned long *frame, int readonly, struct domain *rd)
+{
+ p2m_type_t p2mt;
+ mfn_t mfn;
+ int rc = GNTST_okay;
+
+ if ( readonly )
+ mfn = gfn_to_mfn(rd, gfn, &p2mt);
+ else
+ mfn = gfn_to_mfn_unshare(rd, gfn, &p2mt, 1);
+
+ if ( p2m_is_valid(p2mt) )
+ {
+ *frame = mfn_x(mfn);
+ if ( p2m_is_paging(p2mt) )
+ {
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(rd, gfn);
+ rc = GNTST_eagain;
+ }
+ }
+ else
+ {
+ *frame = INVALID_MFN;
+ rc = GNTST_bad_page;
+ }
+
+ return rc;
+}
+
static inline int
__get_maptrack_handle(
struct grant_table *t)
@@ -527,14 +558,16 @@ __gnttab_map_grant_ref(
if ( !act->pin )
{
+ unsigned long gfn;
+ unsigned long frame;
+
+ gfn = sha1 ? sha1->frame : sha2->full_page.frame;
+ rc = __get_paged_frame(gfn, &frame, !!(op->flags & GNTMAP_readonly), rd);
+ if ( rc != GNTST_okay )
+ goto unlock_out;
+ act->gfn = gfn;
act->domid = ld->domain_id;
- if ( sha1 )
- act->gfn = sha1->frame;
- else
- act->gfn = sha2->full_page.frame;
- act->frame = (op->flags & GNTMAP_readonly) ?
- gmfn_to_mfn(rd, act->gfn) :
- gfn_to_mfn_private(rd, act->gfn);
+ act->frame = frame;
act->start = 0;
act->length = PAGE_SIZE;
act->is_sub_page = 0;
@@ -1697,6 +1730,7 @@ __acquire_grant_for_copy(
domid_t trans_domid;
grant_ref_t trans_gref;
struct domain *rrd;
+ unsigned long gfn;
unsigned long grant_frame;
unsigned trans_page_off;
unsigned trans_length;
@@ -1814,9 +1848,11 @@ __acquire_grant_for_copy(
}
else if ( sha1 )
{
- act->gfn = sha1->frame;
- grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
- gfn_to_mfn_private(rd, act->gfn);
+ gfn = sha1->frame;
+ rc = __get_paged_frame(gfn, &grant_frame, readonly, rd);
+ if ( rc != GNTST_okay )
+ goto unlock_out;
+ act->gfn = gfn;
is_sub_page = 0;
trans_page_off = 0;
trans_length = PAGE_SIZE;
@@ -1824,9 +1860,11 @@ __acquire_grant_for_copy(
}
else if ( !(sha2->hdr.flags & GTF_sub_page) )
{
- act->gfn = sha2->full_page.frame;
- grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
- gfn_to_mfn_private(rd, act->gfn);
+ gfn = sha2->full_page.frame;
+ rc = __get_paged_frame(gfn, &grant_frame, readonly, rd);
+ if ( rc != GNTST_okay )
+ goto unlock_out;
+ act->gfn = gfn;
is_sub_page = 0;
trans_page_off = 0;
trans_length = PAGE_SIZE;
@@ -1834,9 +1872,11 @@ __acquire_grant_for_copy(
}
else
{
- act->gfn = sha2->sub_page.frame;
- grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
- gfn_to_mfn_private(rd, act->gfn);
+ gfn = sha2->sub_page.frame;
+ rc = __get_paged_frame(gfn, &grant_frame, readonly, rd);
+ if ( rc != GNTST_okay )
+ goto unlock_out;
+ act->gfn = gfn;
is_sub_page = 1;
trans_page_off = sha2->sub_page.page_off;
trans_length = sha2->sub_page.length;
@@ -1932,16 +1972,9 @@ __gnttab_copy(
else
{
#ifdef CONFIG_X86
- p2m_type_t p2mt;
- s_frame = mfn_x(gfn_to_mfn(sd, op->source.u.gmfn, &p2mt));
- if ( !p2m_is_valid(p2mt) )
- s_frame = INVALID_MFN;
- if ( p2m_is_paging(p2mt) )
- {
- p2m_mem_paging_populate(sd, op->source.u.gmfn);
- rc = -ENOENT;
+ rc = __get_paged_frame(op->source.u.gmfn, &s_frame, 1, sd);
+ if ( rc != GNTST_okay )
goto error_out;
- }
#else
s_frame = gmfn_to_mfn(sd, op->source.u.gmfn);
#endif
@@ -1978,16 +2011,9 @@ __gnttab_copy(
else
{
#ifdef CONFIG_X86
- p2m_type_t p2mt;
- d_frame = mfn_x(gfn_to_mfn_unshare(dd, op->dest.u.gmfn, &p2mt, 1));
- if ( !p2m_is_valid(p2mt) )
- d_frame = INVALID_MFN;
- if ( p2m_is_paging(p2mt) )
- {
- p2m_mem_paging_populate(dd, op->dest.u.gmfn);
- rc = -ENOENT;
+ rc = __get_paged_frame(op->dest.u.gmfn, &d_frame, 0, dd);
+ if ( rc != GNTST_okay )
goto error_out;
- }
#else
d_frame = gmfn_to_mfn(dd, op->dest.u.gmfn);
#endif
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 15/18] xenpaging: handle dying guest in notify_via_xen_event_channel
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (13 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 14/18] xenpaging: page-in granttable entries Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 16/18] xenpaging: prevent page-out of first 16MB Olaf Hering
` (4 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.notify_via_xen_event_channel.patch --]
[-- Type: text/plain, Size: 845 bytes --]
Avoid crash of Xen if a xenpaging enabled guest crashes and there are still
memevents in flight, as reported here:
http://lists.xensource.com/archives/html/xen-devel/2010-08/msg00516.html
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>
---
xen/common/event_channel.c | 6 ++++++
1 file changed, 6 insertions(+)
--- xen-4.0.1-testing.orig/xen/common/event_channel.c
+++ xen-4.0.1-testing/xen/common/event_channel.c
@@ -994,6 +994,12 @@ void notify_via_xen_event_channel(struct
spin_lock(&ld->event_lock);
+ if ( unlikely(ld->is_dying) )
+ {
+ spin_unlock(&ld->event_lock);
+ return;
+ }
+
ASSERT(port_is_valid(ld, lport));
lchn = evtchn_from_port(ld, lport);
ASSERT(lchn->consumer_is_xen);
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 16/18] xenpaging: prevent page-out of first 16MB
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (14 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 15/18] xenpaging: handle dying guest in notify_via_xen_event_channel Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 17/18] xenpaging: add dynamic startup delay for xenpaging Olaf Hering
` (3 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.blacklist.patch --]
[-- Type: text/plain, Size: 798 bytes --]
This is more a workaround than a bugfix:
Don't page out first 16MB of memory.
When the BIOS does its initialization process and xenpaging removes pages,
crashes will occour due to lack of support of xenpaging.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/xenpaging/policy_default.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- xen-4.0.1-testing.orig/tools/xenpaging/policy_default.c
+++ xen-4.0.1-testing/tools/xenpaging/policy_default.c
@@ -60,8 +60,9 @@ int policy_init(xenpaging_t *paging)
for ( i = 0; i < MRU_SIZE; i++ )
mru[i] = INVALID_MFN;
- /* Don't page out page 0 */
- set_bit(0, bitmap);
+ /* Don't page out first 16MB */
+ for ( i = 0; i < ((16*1024*1024)/4096); i++ )
+ set_bit(i, bitmap);
out:
return rc;
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 17/18] xenpaging: add dynamic startup delay for xenpaging
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (15 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 16/18] xenpaging: prevent page-out of first 16MB Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-15 14:12 ` [PATCH 18/18] xenpaging: random debug statements and partial fixes Olaf Hering
` (2 subsequent siblings)
19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.autostart_delay.patch --]
[-- Type: text/plain, Size: 4269 bytes --]
This is a debug helper. Since the xenpaging support is still fragile, run
xenpaging at different stages in the bootprocess. Different delays will trigger
more bugs. This implementation starts without delay for 5 reboots, then
increments the delay by 0.1 seconds It uses xenstore for presistant storage of
delay values
TODO: find the correct place to remove the xenstore directory when the guest is shutdown or crashed
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
tools/python/xen/xend/image.py | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
--- xen-4.0.1-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.0.1-testing/tools/python/xen/xend/image.py
@@ -123,6 +123,18 @@ class ImageHandler:
self.device_model = vmConfig['platform'].get('device_model')
self.xenpaging = vmConfig['platform'].get('xenpaging')
+ self.xenpaging_delay = xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay" % self.vm.info['name_label'])
+ if self.xenpaging_delay == None:
+ log.warn("XXX creating /local/domain/0/xenpaging/%s % self.vm.info['name_label'])
+ xstransact.Mkdir("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'])
+ xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay', '0.0'))
+ xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay_inc', '0.1'))
+ xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay_use', '5'))
+ xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay_used', '0'))
+ self.xenpaging_delay = float(xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay" % self.vm.info['name_label']))
+ self.xenpaging_delay_inc = float(xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay_inc" % self.vm.info['name_label']))
+ self.xenpaging_delay_use = int(xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay_use" % self.vm.info['name_label']))
+ self.xenpaging_delay_used = int(xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay_used" % self.vm.info['name_label']))
self.display = vmConfig['platform'].get('display')
self.xauthority = vmConfig['platform'].get('xauthority')
@@ -401,6 +413,17 @@ class ImageHandler:
return
if self.xenpaging_pid:
return
+ if self.xenpaging_delay_used < self.xenpaging_delay_use:
+ self.xenpaging_delay_used += 1
+ else:
+ self.xenpaging_delay_used = 0
+ self.xenpaging_delay += self.xenpaging_delay_inc
+ log.info("delay_used %s" % self.xenpaging_delay_used)
+ log.info("delay_use %s" % self.xenpaging_delay_use)
+ log.info("delay %s" % self.xenpaging_delay)
+ log.info("delay_inc %s" % self.xenpaging_delay_inc)
+ xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay', self.xenpaging_delay))
+ xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay_used', self.xenpaging_delay_used))
xenpaging_bin = auxbin.pathTo("xenpaging")
args = [xenpaging_bin]
args = args + ([ "%d" % self.vm.getDomid()])
@@ -430,6 +453,9 @@ class ImageHandler:
except:
log.warn("chdir %s failed" % xenpaging_dir)
try:
+ if self.xenpaging_delay != 0.0:
+ log.info("delaying xenpaging startup %s seconds ..." % self.xenpaging_delay)
+ time.sleep(self.xenpaging_delay)
log.info("starting %s" % args)
os.execve(xenpaging_bin, args, env)
except Exception, e:
@@ -449,6 +475,8 @@ class ImageHandler:
def destroyXenPaging(self):
if self.xenpaging is None:
return
+ # FIXME find correct place for guest shutdown or crash
+ #xstransact.Remove("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'])
if self.xenpaging_pid:
try:
os.kill(self.xenpaging_pid, signal.SIGHUP)
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 18/18] xenpaging: random debug statements and partial fixes
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (16 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 17/18] xenpaging: add dynamic startup delay for xenpaging Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
2010-10-18 16:56 ` Ian Jackson
2010-10-15 15:05 ` [PATCH 00/18] xenpaging changes for 4.0 Dan Magenheimer
2010-10-18 11:26 ` Tim Deegan
19 siblings, 1 reply; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: xenpaging.debug.patch --]
[-- Type: text/plain, Size: 25365 bytes --]
Debug and hacks.
Presented-by: Olaf Hering <olaf@aepfle.de>
---
tools/firmware/hvmloader/util.c | 5 ++++-
tools/libxc/xc_dom_x86.c | 2 ++
tools/libxc/xc_domain.c | 3 +++
tools/libxc/xc_offline_page.c | 1 +
tools/xenpaging/Makefile | 2 +-
tools/xenpaging/xenpaging.c | 26 +++++++++++++++++++++++++-
tools/xentrace/formats | 5 +++++
xen/arch/x86/debug.c | 2 ++
xen/arch/x86/hvm/svm/svm.c | 2 ++
xen/arch/x86/hvm/vmx/vmx.c | 4 ++++
xen/arch/x86/mm.c | 26 +++++++++++++++++++++++++-
xen/arch/x86/mm/hap/guest_walk.c | 2 ++
xen/arch/x86/mm/mem_event.c | 9 +++++++++
xen/arch/x86/mm/mem_sharing.c | 4 ++++
xen/arch/x86/mm/p2m.c | 7 +++++++
xen/arch/x86/mm/shadow/common.c | 4 ++++
xen/arch/x86/mm/shadow/multi.c | 2 ++
xen/common/grant_table.c | 27 ++++++++++++++++++++++-----
xen/common/memory.c | 3 +++
xen/include/asm-x86/p2m.h | 4 ++++
20 files changed, 131 insertions(+), 9 deletions(-)
--- xen-4.0.1-testing.orig/tools/firmware/hvmloader/util.c
+++ xen-4.0.1-testing/tools/firmware/hvmloader/util.c
@@ -329,7 +329,7 @@ void *mem_alloc(uint32_t size, uint32_t
mfn = reserve >> PAGE_SHIFT;
/* Try to allocate a brand new page in the reserved area. */
- if ( !over_allocated )
+ if ( 0 && !over_allocated )
{
uint8_t delay = 0;
xmr.domid = DOMID_SELF;
@@ -339,6 +339,7 @@ void *mem_alloc(uint32_t size, uint32_t
set_xen_guest_handle(xmr.extent_start, &mfn);
do {
rc = hypercall_memory_op(XENMEM_populate_physmap, &xmr);
+ printf("%s(%u): %x %x\n", __func__,__LINE__,rc, delay);
if ( rc == 0 )
cpu_relax();
} while ( rc == 0 && ++delay );
@@ -364,6 +365,7 @@ void *mem_alloc(uint32_t size, uint32_t
xatp.gpfn = mfn;
do {
rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+ printf("%s(%u): %x\n", __func__,__LINE__,rc);
if ( rc == -ENOENT )
cpu_relax();
} while ( rc == -ENOENT );
@@ -622,6 +624,7 @@ uint16_t get_cpu_mhz(void)
xatp.gpfn = (unsigned long)shared_info >> 12;
do {
rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+ printf("%s(%u): %x\n", __func__,__LINE__,rc);
if ( rc == -ENOENT )
cpu_relax();
} while ( rc == -ENOENT );
--- xen-4.0.1-testing.orig/tools/libxc/xc_dom_x86.c
+++ xen-4.0.1-testing/tools/libxc/xc_dom_x86.c
@@ -812,6 +812,7 @@ int arch_setup_bootlate(struct xc_dom_im
rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp);
if ( rc != 0 )
{
+ fprintf(stderr, "%s(%u) rc %x errno %x\n", __func__,__LINE__,rc,errno);
xc_dom_panic(XC_INTERNAL_ERROR, "%s: mapping shared_info failed "
"(pfn=0x%" PRIpfn ", rc=%d)\n",
__FUNCTION__, xatp.gpfn, rc);
@@ -828,6 +829,7 @@ int arch_setup_bootlate(struct xc_dom_im
rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp);
if ( rc != 0 )
{
+ fprintf(stderr, "%s(%u) rc %x errno %x\n", __func__,__LINE__,rc,errno);
if ( (i > 0) && (errno == EINVAL) )
{
xc_dom_printf("%s: %d grant tables mapped\n", __FUNCTION__,
--- xen-4.0.1-testing.orig/tools/libxc/xc_domain.c
+++ xen-4.0.1-testing/tools/libxc/xc_domain.c
@@ -564,7 +564,10 @@ static int do_xenmem_op_retry(int xc_han
}
if ( err )
+ {
+ fprintf(stderr, "%s: delay reset: %d err %x count %lx start %lx delay %lu/%lu\n",__func__,cmd,err,count,start,delay,delay/666);
delay = 0;
+ }
start += err;
count -= err;
--- xen-4.0.1-testing.orig/tools/libxc/xc_offline_page.c
+++ xen-4.0.1-testing/tools/libxc/xc_offline_page.c
@@ -517,6 +517,7 @@ static int exchange_page(int xc_handle,
set_xen_guest_handle(exchange.out.extent_start, &out_mfn);
rc = xc_memory_op(xc_handle, XENMEM_exchange, &exchange);
+ fprintf(stderr, "%s(%u) rc %x errno %x\n", __func__,__LINE__,rc,errno);
if (!rc)
*new_mfn = out_mfn;
--- xen-4.0.1-testing.orig/tools/xenpaging/Makefile
+++ xen-4.0.1-testing/tools/xenpaging/Makefile
@@ -4,7 +4,7 @@ include $(XEN_ROOT)/tools/Rules.mk
CFLAGS += -I $(XEN_XC)
CFLAGS += -I ./
CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore)
-LDFLAGS += $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenstore)
+LDFLAGS += $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenstore) -lrt
POLICY = default
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -21,6 +21,7 @@
#include <inttypes.h>
+#include <time.h>
#include <stdlib.h>
#include <signal.h>
#include <xc_private.h>
@@ -249,6 +250,7 @@ int xenpaging_teardown(xenpaging_t *pagi
rc = xc_mem_event_disable(paging->xc_handle, paging->mem_event.domain_id);
if ( rc != 0 )
{
+ fprintf(stderr, "%s: rc %x errno %x\n", __func__, rc, errno);
ERROR("Error tearing down domain paging in xen");
}
@@ -370,6 +372,7 @@ int xenpaging_evict_page(xenpaging_t *pa
goto out;
}
+ fprintf(stderr, "%s(%u) > gfn %lx pageslot %d\n", __func__, __LINE__, victim->gfn, i);
/* Notify policy of page being paged out */
policy_notify_paged_out(paging->mem_event.domain_id, victim->gfn);
@@ -406,6 +409,8 @@ static int xenpaging_populate_page(
void *page;
int ret;
+ _gfn = *gfn;
+ fprintf(stderr, "%s(%u) < gfn %lx pageslot %d\n", __func__, __LINE__, _gfn, i);
/* Tell Xen to allocate a page for the domain */
ret = xc_mem_paging_prep(paging->xc_handle, paging->mem_event.domain_id,
*gfn);
@@ -441,6 +446,17 @@ static int xenpaging_populate_page(
return ret;
}
+static void time_diff(struct timespec *start, struct timespec *end, struct timespec *diff)
+{
+ if ((end->tv_nsec - start->tv_nsec) < 0) {
+ diff->tv_sec = end->tv_sec - start->tv_sec - 1;
+ diff->tv_nsec = 1000000000 + end->tv_nsec - start->tv_nsec;
+ } else {
+ diff->tv_sec = end->tv_sec - start->tv_sec;
+ diff->tv_nsec = end->tv_nsec - start->tv_nsec;
+ }
+}
+
static int evict_victim(xenpaging_t *paging, domid_t domain_id,
xenpaging_victim_t *victim, int fd, int i)
{
@@ -501,6 +517,7 @@ int main(int argc, char *argv[])
mode_t open_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
char filename[80];
int fd;
+ struct timespec ce, cl, cd;
if ( argc != 3 )
{
@@ -544,6 +561,8 @@ int main(int argc, char *argv[])
/* Evict pages */
memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
+ if (clock_gettime(CLOCK_MONOTONIC, &ce))
+ perror("clock_gettime");
for ( i = 0; i < num_pages; i++ )
{
rc = evict_victim(paging, domain_id, &victims[i], fd, i);
@@ -554,7 +573,10 @@ int main(int argc, char *argv[])
if ( i % 100 == 0 )
DPRINTF("%d pages evicted\n", i);
}
-
+ if (clock_gettime(CLOCK_MONOTONIC, &cl))
+ perror("clock_gettime");
+ time_diff(&ce, &cl, &cd);
+ DPRINTF("%s: c %d.%09d\n", __func__, (int)cd.tv_sec, (int)cd.tv_nsec);
DPRINTF("pages evicted\n");
/* Swap pages in and out */
@@ -625,8 +647,10 @@ int main(int argc, char *argv[])
else
{
DPRINTF("page already populated (domain = %d; vcpu = %d;"
+ " p2mt = %x;"
" gfn = %"PRIx64"; paused = %"PRId64")\n",
paging->mem_event.domain_id, req.vcpu_id,
+ req.p2mt,
req.gfn, req.flags & MEM_EVENT_FLAG_VCPU_PAUSED);
/* Tell Xen to resume the vcpu */
--- xen-4.0.1-testing.orig/tools/xentrace/formats
+++ xen-4.0.1-testing/tools/xentrace/formats
@@ -5,6 +5,7 @@
0x0001f003 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_change 0x%(1)08x
0x0001f004 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) trace_irq [ vector = %(1)d, count = %(2)d, tot_cycles = 0x%(3)08x, max_cycles = 0x%(4)08x ]
+0x00021002 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) continue_running [ dom:vcpu = 0x%(1)08x ]
0x00021011 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) running_to_runnable [ dom:vcpu = 0x%(1)08x ]
0x00021021 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) running_to_blocked [ dom:vcpu = 0x%(1)08x ]
0x00021031 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) running_to_offline [ dom:vcpu = 0x%(1)08x ]
@@ -70,10 +71,14 @@
0x00082018 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) CLTS
0x00082019 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) LMSW [ value = 0x%(1)08x ]
0x00082119 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) LMSW [ value = 0x%(2)08x%(1)08x ]
+0x00082020 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) INTR_WINDOW [ value = 0x%(1)08x ]
+0x00082021 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) NPF [ gpa = 0x%(2)08x%(1)08x mfn = 0x%(4)08x%(3)08x qual = 0x%(5)04x p2mt = 0x%(6)04x ]
0x0010f001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) page_grant_map [ domid = %(1)d ]
0x0010f002 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) page_grant_unmap [ domid = %(1)d ]
0x0010f003 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) page_grant_transfer [ domid = %(1)d ]
+0x0010f004 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) p2m_set_entry [ gfn 0x%(2)08x%(1)08x mfn 0x%(4)08x%(3)08x pmt 0x%(5)08x domain:order 0x%(6)08x ]
+0x0010f005 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) decrease_reservation [ gfn 0x%(2)08x%(1)08x domain:order 0x%(3)08x ]
0x0020f001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) hypercall [ eip = 0x%(1)08x, eax = 0x%(2)08x ]
0x0020f101 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) hypercall [ rip = 0x%(2)08x%(1)08x, eax = 0x%(3)08x ]
--- xen-4.0.1-testing.orig/xen/arch/x86/debug.c
+++ xen-4.0.1-testing/xen/arch/x86/debug.c
@@ -62,6 +62,8 @@ dbg_hvm_va2mfn(dbgva_t vaddr, struct dom
}
mfn = mfn_x(gfn_to_mfn(dp, gfn, &gfntype));
+if ( p2m_is_paging(gfntype) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,gfntype);
if ( p2m_is_readonly(gfntype) && toaddr )
{
DBGP2("kdb:p2m_is_readonly: gfntype:%x\n", gfntype);
--- xen-4.0.1-testing.orig/xen/arch/x86/hvm/svm/svm.c
+++ xen-4.0.1-testing/xen/arch/x86/hvm/svm/svm.c
@@ -232,6 +232,8 @@ static int svm_vmcb_restore(struct vcpu
if ( c->cr0 & X86_CR0_PG )
{
mfn = mfn_x(gfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT, &p2mt));
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %"PRIx64" p2m %x\n",__func__,c->cr3,p2mt);
if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) )
{
gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64"\n",
--- xen-4.0.1-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
+++ xen-4.0.1-testing/xen/arch/x86/hvm/vmx/vmx.c
@@ -496,6 +496,8 @@ static int vmx_restore_cr0_cr3(
if ( cr0 & X86_CR0_PG )
{
mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt));
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,cr3,p2mt);
if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) )
{
gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%lx\n", cr3);
@@ -1012,6 +1014,8 @@ static void vmx_load_pdptrs(struct vcpu
goto crash;
mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt));
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,cr3,p2mt);
if ( !p2m_is_ram(p2mt) )
goto crash;
--- xen-4.0.1-testing.orig/xen/arch/x86/mm.c
+++ xen-4.0.1-testing/xen/arch/x86/mm.c
@@ -3148,7 +3148,8 @@ int do_mmu_update(
rc = -ENOENT;
break;
- }
+ } else if ( p2m_is_paging(p2mt) )
+ MEM_LOG("gfn %lx p2m %x", gmfn, p2mt);
if ( unlikely(!get_page_from_pagenr(mfn, pt_owner)) )
{
@@ -3224,6 +3225,8 @@ int do_mmu_update(
rc = -ENOENT;
break;
}
+ else if ( p2m_is_paging(l2e_p2mt) )
+ MEM_LOG("gfn %lx p2m %x", l2e_get_pfn(l2e), l2e_p2mt);
else if ( p2m_ram_shared == l2e_p2mt )
{
MEM_LOG("Unexpected attempt to map shared page.\n");
@@ -3254,6 +3257,8 @@ int do_mmu_update(
rc = -ENOENT;
break;
}
+ else if ( p2m_is_paging(l3e_p2mt) )
+ MEM_LOG("gfn %lx p2m %x", l3e_get_pfn(l3e), l3e_p2mt);
else if ( p2m_ram_shared == l3e_p2mt )
{
MEM_LOG("Unexpected attempt to map shared page.\n");
@@ -3285,6 +3290,8 @@ int do_mmu_update(
rc = -ENOENT;
break;
}
+ else if ( p2m_is_paging(l4e_p2mt) )
+ MEM_LOG("gfn %lx p2m %x", l4e_get_pfn(l4e), l4e_p2mt);
else if ( p2m_ram_shared == l4e_p2mt )
{
MEM_LOG("Unexpected attempt to map shared page.\n");
@@ -4322,6 +4329,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
tmp_mfn = mfn_x(gfn_to_mfn_unshare(d, xatp.idx, &p2mt, 0));
if ( unlikely(p2m_is_paging(p2mt)) )
{
+printk("%s(%u) gfn %lx p2m %x\n",__func__,__LINE__,xatp.idx, p2mt);
if ( p2m_is_paged(p2mt) )
p2m_mem_paging_populate(d, xatp.idx);
rcu_unlock_domain(d);
@@ -4337,6 +4345,21 @@ long arch_memory_op(int op, XEN_GUEST_HA
break;
mfn = tmp_mfn;
page = mfn_to_page(mfn);
+
+ gpfn = get_gpfn_from_mfn(tmp_mfn);
+ ASSERT( gpfn != SHARED_M2P_ENTRY );
+ gfn_to_mfn(d, gpfn, &p2mt);
+ if ( unlikely(p2m_is_paging(p2mt)) )
+ {
+printk("%s(%u) gfn %lx p2m %x\n",__func__,__LINE__, gpfn, p2mt);
+ if ( page )
+ put_page(page);
+ if ( p2m_is_paged(p2mt) )
+ p2m_mem_paging_populate(d, gpfn);
+ rcu_unlock_domain(d);
+ return -ENOENT;
+ }
+
break;
}
default:
@@ -4369,6 +4392,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
rc = guest_remove_page(d, xatp.gpfn);
if ( rc == -ENOENT )
{
+ MEM_LOG("gfn %lx", xatp.gpfn);
domain_unlock(d);
rcu_unlock_domain(d);
return rc;
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/hap/guest_walk.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/hap/guest_walk.c
@@ -49,6 +49,7 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
top_mfn = gfn_to_mfn_unshare(v->domain, cr3 >> PAGE_SHIFT, &p2mt, 0);
if ( p2m_is_paging(p2mt) )
{
+printk("%s: gfn %lx p2m %x\n",__func__,cr3 >> PAGE_SHIFT,p2mt);
if ( p2m_is_paged(p2mt) )
p2m_mem_paging_populate(v->domain, cr3 >> PAGE_SHIFT);
@@ -82,6 +83,7 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
gfn_to_mfn_unshare(v->domain, gfn_x(gfn), &p2mt, 0);
if ( p2m_is_paging(p2mt) )
{
+printk("%s: gfn %lx p2m %x\n",__func__,gfn_x(gfn),p2mt);
if ( p2m_is_paged(p2mt) )
p2m_mem_paging_populate(v->domain, gfn_x(gfn));
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/mem_event.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/mem_event.c
@@ -68,6 +68,7 @@ int mem_event_enable(struct domain *d, m
d->mem_event.paused = 0;
d->mem_event.enabled = 1;
+printk("%s %u\n",__func__, d->domain_id);
return 0;
err_shared:
@@ -82,6 +83,7 @@ int mem_event_enable(struct domain *d, m
int mem_event_disable(struct domain *d)
{
+printk("%s %u\n",__func__, d->domain_id);
d->mem_event.enabled = 0;
d->mem_event.paused = 0;
@@ -168,6 +170,9 @@ int mem_event_check_ring(struct domain *
mem_event_ring_lock(d);
free_requests = RING_FREE_REQUESTS(&d->mem_event.front_ring);
+ if ( free_requests < 3 )
+ gdprintk(XENLOG_INFO, "frq %d\n", free_requests);
+ WARN_ON(free_requests == 0);
ring_full = free_requests < MEM_EVENT_RING_THRESHOLD;
if ( (current->domain->domain_id == d->domain_id) && ring_full )
@@ -243,6 +248,8 @@ int mem_event_domctl(struct domain *d, x
guest_get_eff_l1e(v, ring_addr, &l1e);
gfn = l1e_get_pfn(l1e);
ring_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,p2mt);
rc = -EINVAL;
if ( unlikely(!mfn_valid(mfn_x(ring_mfn))) )
@@ -252,6 +259,8 @@ int mem_event_domctl(struct domain *d, x
guest_get_eff_l1e(v, shared_addr, &l1e);
gfn = l1e_get_pfn(l1e);
shared_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,p2mt);
rc = -EINVAL;
if ( unlikely(!mfn_valid(mfn_x(shared_mfn))) )
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/mem_sharing.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/mem_sharing.c
@@ -381,6 +381,8 @@ int mem_sharing_debug_gfn(struct domain
struct page_info *page;
mfn = gfn_to_mfn(d, gfn, &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,p2mt);
page = mfn_to_page(mfn);
printk("Debug for domain=%d, gfn=%lx, ",
@@ -636,6 +638,8 @@ int mem_sharing_unshare_page(struct doma
struct list_head *le;
mfn = gfn_to_mfn(d, gfn, &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,p2mt);
page = mfn_to_page(mfn);
handle = page->shr_handle;
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c
@@ -2005,6 +2005,8 @@ p2m_remove_page(struct domain *d, unsign
mfn_return = d->arch.p2m->get_entry(d, gfn + i, &t, p2m_query);
if ( !p2m_is_grant(t) )
set_gpfn_from_mfn(mfn+i, INVALID_M2P_ENTRY);
+ if (!( !p2m_is_valid(t) || mfn + i == mfn_x(mfn_return) ))
+ printk("%s(%u) i %lu t %x gfn %lx mfn %lx ret %lx %lu %d\n",__func__,__LINE__,i,t,gfn,mfn,mfn_x(mfn_return), p2m_is_valid(t), mfn + i == mfn_x(mfn_return));
ASSERT( !p2m_is_valid(t) || mfn + i == mfn_x(mfn_return) );
}
set_p2m_entry(d, gfn, _mfn(INVALID_MFN), page_order, p2m_invalid);
@@ -2115,6 +2117,8 @@ guest_physmap_add_entry(struct domain *d
int pod_count = 0;
int rc = 0;
+ if ( p2m_is_paging(t) )
+ gdprintk(XENLOG_ERR, "d %u gfn %lx mfn %lx o %x p2m %x\n", d->domain_id, gfn, mfn, page_order, t);
if ( !paging_mode_translate(d) )
{
if ( need_iommu(d) && t == p2m_ram_rw )
@@ -2147,6 +2151,8 @@ guest_physmap_add_entry(struct domain *d
for ( i = 0; i < (1UL << page_order); i++ )
{
omfn = gfn_to_mfn_query(d, gfn + i, &ot);
+ if ( p2m_is_paging(ot) )
+ gdprintk(XENLOG_ERR, "d %u gfn %lx omfn %lx o %x i %lx p2m %x\n", d->domain_id, gfn, mfn_x(omfn), page_order, i, ot);
if ( p2m_is_grant(ot) )
{
/* Really shouldn't be unmapping grant maps this way */
@@ -2188,6 +2194,7 @@ guest_physmap_add_entry(struct domain *d
omfn = gfn_to_mfn_query(d, ogfn, &ot);
if ( unlikely(p2m_is_paging(ot)) )
{
+ gdprintk(XENLOG_ERR, "d %u gfn %lx omfn %lx o %x i %lx p2m %x\n", d->domain_id, ogfn, mfn_x(omfn), page_order, i, ot);
p2m_unlock(d->arch.p2m);
if ( p2m_is_paged(ot) )
p2m_mem_paging_populate(d, ogfn);
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/shadow/common.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/shadow/common.c
@@ -3720,6 +3720,8 @@ int shadow_track_dirty_vram(struct domai
int dirty = 0;
paddr_t sl1ma = dirty_vram->sl1ma[i];
+if ( p2m_is_paging(t) )
+printk("%s: gfn %lx p2m %x\n",__func__,begin_pfn +i,t);
if (mfn_x(mfn) == INVALID_MFN)
{
dirty = 1;
@@ -3801,6 +3803,8 @@ int shadow_track_dirty_vram(struct domai
* write access */
for ( i = begin_pfn; i < end_pfn; i++ ) {
mfn_t mfn = gfn_to_mfn(d, i, &t);
+if ( p2m_is_paging(t) )
+printk("%s: gfn %lx p2m %x\n",__func__,i,t);
if (mfn_x(mfn) != INVALID_MFN)
flush_tlb |= sh_remove_write_access(d->vcpu[0], mfn, 1, 0);
}
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/shadow/multi.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/shadow/multi.c
@@ -4795,6 +4795,8 @@ static mfn_t emulate_gva_to_mfn(struct v
mfn = gfn_to_mfn_query(v->domain, _gfn(gfn), &p2mt);
else
mfn = gfn_to_mfn(v->domain, _gfn(gfn), &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__, gfn,p2mt);
if ( p2m_is_readonly(p2mt) )
return _mfn(READONLY_GFN);
--- xen-4.0.1-testing.orig/xen/common/grant_table.c
+++ xen-4.0.1-testing/xen/common/grant_table.c
@@ -1447,6 +1447,7 @@ gnttab_transfer(
struct domain *d = current->domain;
struct domain *e;
struct page_info *page;
+ int rc;
int i;
struct gnttab_transfer gop;
unsigned long mfn;
@@ -1465,7 +1466,12 @@ gnttab_transfer(
return -EFAULT;
}
- mfn = gfn_to_mfn_private(d, gop.mfn);
+ rc = __get_paged_frame(gop.mfn, &mfn, 0, d);
+ if ( rc == GNTST_eagain )
+ {
+ gop.status = GNTST_eagain;
+ goto copyback;
+ }
/* Check the passed page frame for basic validity. */
if ( unlikely(!mfn_valid(mfn)) )
@@ -1580,28 +1586,39 @@ gnttab_transfer(
/* Tell the guest about its new page frame. */
spin_lock(&e->grant_table->lock);
+ gop.status = GNTST_okay;
+
if ( e->grant_table->gt_version == 1 )
{
grant_entry_v1_t *sha = &shared_entry_v1(e->grant_table, gop.ref);
- guest_physmap_add_page(e, sha->frame, mfn, 0);
+ rc = guest_physmap_add_page(e, sha->frame, mfn, 0);
+ if ( rc == -ENOENT )
+ {
+ gop.status = GNTST_eagain;
+ goto unlock_granttable_and_copyback;
+ }
sha->frame = mfn;
}
else
{
grant_entry_v2_t *sha = &shared_entry_v2(e->grant_table, gop.ref);
- guest_physmap_add_page(e, sha->full_page.frame, mfn, 0);
+ rc = guest_physmap_add_page(e, sha->full_page.frame, mfn, 0);
+ if ( rc == -ENOENT )
+ {
+ gop.status = GNTST_eagain;
+ goto unlock_granttable_and_copyback;
+ }
sha->full_page.frame = mfn;
}
wmb();
shared_entry_header(e->grant_table, gop.ref)->flags |=
GTF_transfer_completed;
+ unlock_granttable_and_copyback:
spin_unlock(&e->grant_table->lock);
rcu_unlock_domain(e);
- gop.status = GNTST_okay;
-
copyback:
if ( unlikely(__copy_to_guest_offset(uop, i, &gop, 1)) )
{
--- xen-4.0.1-testing.orig/xen/common/memory.c
+++ xen-4.0.1-testing/xen/common/memory.c
@@ -138,6 +138,7 @@ static void populate_physmap(struct memo
rc = guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
if ( rc != 0 )
{
+ gdprintk(XENLOG_INFO, "%s: rc %x\n", __func__, rc);
free_domheap_pages(page, a->extent_order);
goto out;
}
@@ -170,6 +171,7 @@ int guest_remove_page(struct domain *d,
mfn = mfn_x(gfn_to_mfn(d, gmfn, &p2mt));
if ( unlikely(p2m_is_paging(p2mt)) )
{
+ gdprintk(XENLOG_INFO, "d %u gfn %lx mfn %lx p2m %x\n", d->domain_id, gmfn, mfn, p2mt);
if ( p2m_is_paged(p2mt) )
p2m_mem_paging_populate(d, gmfn);
return -ENOENT;
@@ -374,6 +376,7 @@ static long memory_exchange(XEN_GUEST_HA
mfn = mfn_x(gfn_to_mfn_unshare(d, gmfn + k, &p2mt, 0));
if ( p2m_is_paging(p2mt) )
{
+ printk("%s: gfn %lx p2m %x\n",__func__,gmfn+k,p2mt);
if ( p2m_is_paged(p2mt) )
p2m_mem_paging_populate(d, gmfn);
rc = -ENOENT;
--- xen-4.0.1-testing.orig/xen/include/asm-x86/p2m.h
+++ xen-4.0.1-testing/xen/include/asm-x86/p2m.h
@@ -329,6 +329,8 @@ static inline mfn_t gfn_to_mfn_unshare(s
return mfn;
}
mfn = gfn_to_mfn(d, gfn, p2mt);
+if ( p2m_is_paging(*p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__, gfn,*p2mt);
}
#endif
@@ -342,6 +344,8 @@ static inline unsigned long gmfn_to_mfn(
mfn_t mfn;
p2m_type_t t;
mfn = gfn_to_mfn(d, gpfn, &t);
+if ( p2m_is_paging(t) )
+printk("%s: gfn %lx p2m %x\n",__func__, gpfn,t);
if ( p2m_is_valid(t) )
return mfn_x(mfn);
return INVALID_MFN;
^ permalink raw reply [flat|nested] 31+ messages in thread* RE: [PATCH 00/18] xenpaging changes for 4.0
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (17 preceding siblings ...)
2010-10-15 14:12 ` [PATCH 18/18] xenpaging: random debug statements and partial fixes Olaf Hering
@ 2010-10-15 15:05 ` Dan Magenheimer
2010-10-18 13:03 ` Olaf Hering
2010-10-22 8:55 ` Olaf Hering
2010-10-18 11:26 ` Tim Deegan
19 siblings, 2 replies; 31+ messages in thread
From: Dan Magenheimer @ 2010-10-15 15:05 UTC (permalink / raw)
To: Olaf Hering, xen-devel
Hi Olaf --
Since you have obviously become an expert user of xenpaging,
any chance you could write brief how-to documentation for it
and maybe add a file to xen.hg/docs/misc?
Thanks,
Dan
> -----Original Message-----
> From: Olaf Hering [mailto:olaf@aepfle.de]
> Sent: Friday, October 15, 2010 8:12 AM
> To: xen-devel@lists.xensource.com
> Subject: [Xen-devel] [PATCH 00/18] xenpaging changes for 4.0
>
>
> Here are some changes for xenpaging in the 4.0 branch.
>
> Its just for review and comments. All changes are also needed for
> xen-unstable, I will prepare a patch queue also for this branch.
>
> There are still issues with xenpaging.
> My testsetup is a SLES11 SP1 guest with runlevel 6 as default runlevel
> to
> trigger automatic reboot. After a few iterations, there will be MMIO
> emulation
> errors. This happens with a startup delay of 15.0 seconds.
>
> Another issue:
> If the startup delay is 0.0, and over_allocated in hvmloader mem_alloc
> is
> forced to be active, the ASSERT in p2m_remove_page() triggers. This is
> because
> the passed mfn and the mfn returned by ->get_entry() do not match. So
> far I
> have no idea where the appearently missing set_gpfn_from_mfn() should
> go to.
> Normally over_allocated is not set because the XENMEM_populate_physmap
> call
> does not fail.
>
> Olaf
>
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 00/18] xenpaging changes for 4.0
2010-10-15 15:05 ` [PATCH 00/18] xenpaging changes for 4.0 Dan Magenheimer
@ 2010-10-18 13:03 ` Olaf Hering
2010-10-22 8:55 ` Olaf Hering
1 sibling, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-18 13:03 UTC (permalink / raw)
To: Dan Magenheimer; +Cc: xen-devel
On Fri, Oct 15, Dan Magenheimer wrote:
> Hi Olaf --
>
> Since you have obviously become an expert user of xenpaging,
> any chance you could write brief how-to documentation for it
> and maybe add a file to xen.hg/docs/misc?
Dan,
yes I will write something, which I will send with the next round of
patches for xen-unstable.
Olaf
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 00/18] xenpaging changes for 4.0
2010-10-15 15:05 ` [PATCH 00/18] xenpaging changes for 4.0 Dan Magenheimer
2010-10-18 13:03 ` Olaf Hering
@ 2010-10-22 8:55 ` Olaf Hering
1 sibling, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-22 8:55 UTC (permalink / raw)
To: Dan Magenheimer; +Cc: xen-devel
On Fri, Oct 15, Dan Magenheimer wrote:
> Hi Olaf --
>
> Since you have obviously become an expert user of xenpaging,
> any chance you could write brief how-to documentation for it
> and maybe add a file to xen.hg/docs/misc?
This is a first draft.
Subject: xenpaging: (sparse) documenation
Write up some sparse documentation about xenpaging usage.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
docs/misc/xenpaging.txt | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
--- /dev/null
+++ xen-4.0.1-testing/docs/misc/xenpaging.txt
@@ -0,0 +1,40 @@
+Warning:
+
+The xenpaging code is new and not fully debugged.
+Usage of xenpaging can crash Xen or cause severe data corruption in the
+guest memory and its filesystems!
+
+Description:
+
+xenpaging writes memory pages of a given guest to a file and moves the
+page back to the pool of available memory. Once the guests wants to
+access the paged-out memory, the page is read from disk and placed into
+memory. This allows the sum of all running guests to use more memory
+than physically available on the host.
+
+Usage:
+
+Once the guest is running, run xenpaging with the guest_id and the
+number of pages to page-out:
+
+ mkdir /var/lib/xen/xenpaging
+ chdir /var/lib/xen/xenpaging
+ xenpaging <guest_id> <number_of_pages>
+
+To obtain the guest_id, run 'xm list'.
+xenpaging will write the pagefile to the current directory.
+Example with 128MB pagefile on guest 1:
+
+ xenpaging 1 32768
+
+Caution: stopping xenpaging manually will cause the guest to stall or
+crash because the paged-out memory is not written back into the guest!
+
+
+
+Todo:
+- implement stopping of xenpaging
+- implement/test live migration
+
+
+# vim: tw=72
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 00/18] xenpaging changes for 4.0
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
` (18 preceding siblings ...)
2010-10-15 15:05 ` [PATCH 00/18] xenpaging changes for 4.0 Dan Magenheimer
@ 2010-10-18 11:26 ` Tim Deegan
2010-10-18 13:06 ` Olaf Hering
2010-10-18 16:57 ` Ian Jackson
19 siblings, 2 replies; 31+ messages in thread
From: Tim Deegan @ 2010-10-18 11:26 UTC (permalink / raw)
To: Olaf Hering; +Cc: xen-devel@lists.xensource.com
Hi Olaf,
Thanks for all your work on this!
These patches look pretty good to me, with a few caveats:
- Is it possible to avoid having quite so many paths return ENOENT?
In particular, there seemed to be paths where _removing_ a p2m entry
that's paged out caused an error. Would it be possible to have some of
those cases fixed up from the paging code instead?
- The usual way to get patches into the 4.0 tree is to submit them
againts xen-unstable and then ask for specific patches to be
backported; I see you're already going that way with most of these.
- I imagine the tools maintainers will encourage you to do your tools
patches againsl xl/libxl as well. :)
Cheers,
Tim.
At 15:12 +0100 on 15 Oct (1287155522), Olaf Hering wrote:
> Here are some changes for xenpaging in the 4.0 branch.
>
> Its just for review and comments. All changes are also needed for
> xen-unstable, I will prepare a patch queue also for this branch.
>
> There are still issues with xenpaging.
> My testsetup is a SLES11 SP1 guest with runlevel 6 as default runlevel to
> trigger automatic reboot. After a few iterations, there will be MMIO emulation
> errors. This happens with a startup delay of 15.0 seconds.
>
> Another issue:
> If the startup delay is 0.0, and over_allocated in hvmloader mem_alloc is
> forced to be active, the ASSERT in p2m_remove_page() triggers. This is because
> the passed mfn and the mfn returned by ->get_entry() do not match. So far I
> have no idea where the appearently missing set_gpfn_from_mfn() should go to.
> Normally over_allocated is not set because the XENMEM_populate_physmap call
> does not fail.
>
> Olaf
>
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
--
Tim Deegan <Tim.Deegan@citrix.com>
Principal Software Engineer, XenServer Engineering
Citrix Systems UK Ltd. (Company #02937203, SL9 0BG)
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH 00/18] xenpaging changes for 4.0
2010-10-18 11:26 ` Tim Deegan
@ 2010-10-18 13:06 ` Olaf Hering
2010-10-22 9:04 ` Tim Deegan
2010-10-18 16:57 ` Ian Jackson
1 sibling, 1 reply; 31+ messages in thread
From: Olaf Hering @ 2010-10-18 13:06 UTC (permalink / raw)
To: Tim Deegan; +Cc: xen-devel@lists.xensource.com
On Mon, Oct 18, Tim Deegan wrote:
> These patches look pretty good to me, with a few caveats:
> - Is it possible to avoid having quite so many paths return ENOENT?
> In particular, there seemed to be paths where _removing_ a p2m entry
> that's paged out caused an error. Would it be possible to have some of
> those cases fixed up from the paging code instead?
I'm not sure if thats possible.
Thats currently beyond my knowledge, sorry.
Any pointer for how to do that are welcome.
> - The usual way to get patches into the 4.0 tree is to submit them
> againts xen-unstable and then ask for specific patches to be
> backported; I see you're already going that way with most of these.
Yes, just wanted to send my current state and all of them are also
needed for xen-unstable
> - I imagine the tools maintainers will encourage you to do your tools
> patches againsl xl/libxl as well. :)
Sure, that will be done as well.
Olaf
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 00/18] xenpaging changes for 4.0
2010-10-18 13:06 ` Olaf Hering
@ 2010-10-22 9:04 ` Tim Deegan
0 siblings, 0 replies; 31+ messages in thread
From: Tim Deegan @ 2010-10-22 9:04 UTC (permalink / raw)
To: Olaf Hering; +Cc: xen-devel@lists.xensource.com
At 14:06 +0100 on 18 Oct (1287410805), Olaf Hering wrote:
> On Mon, Oct 18, Tim Deegan wrote:
>
> > These patches look pretty good to me, with a few caveats:
> > - Is it possible to avoid having quite so many paths return ENOENT?
> > In particular, there seemed to be paths where _removing_ a p2m entry
> > that's paged out caused an error. Would it be possible to have some of
> > those cases fixed up from the paging code instead?
>
> I'm not sure if thats possible.
OK, having had a look I'm not sure it's possible either. :) Your
current approach should be OK.
Cheers,
Tim.
--
Tim Deegan <Tim.Deegan@citrix.com>
Principal Software Engineer, XenServer Engineering
Citrix Systems UK Ltd. (Company #02937203, SL9 0BG)
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 00/18] xenpaging changes for 4.0
2010-10-18 11:26 ` Tim Deegan
2010-10-18 13:06 ` Olaf Hering
@ 2010-10-18 16:57 ` Ian Jackson
1 sibling, 0 replies; 31+ messages in thread
From: Ian Jackson @ 2010-10-18 16:57 UTC (permalink / raw)
To: Tim Deegan; +Cc: Olaf Hering, xen-devel@lists.xensource.com
Tim Deegan writes ("Re: [Xen-devel] [PATCH 00/18] xenpaging changes for 4.0"):
> - The usual way to get patches into the 4.0 tree is to submit them
> againts xen-unstable and then ask for specific patches to be
> backported; I see you're already going that way with most of these.
I would certainly like to try out these changes in xen-unstable
first.
> - I imagine the tools maintainers will encourage you to do your tools
> patches againsl xl/libxl as well. :)
Yes, in xen-unstable at least.
Ian.
^ permalink raw reply [flat|nested] 31+ messages in thread