All of lore.kernel.org
 help / color / mirror / Atom feed
* inaccurate dirty_count from XEN_DOMCTL_SHADOW_OP
@ 2017-03-21  9:50 Olaf Hering
  2017-03-22 10:46 ` Olaf Hering
  0 siblings, 1 reply; 6+ messages in thread
From: Olaf Hering @ 2017-03-21  9:50 UTC (permalink / raw)
  To: xen-devel


[-- Attachment #1.1.1: Type: text/plain, Size: 438 bytes --]

To measure how many dirty pages a domU creates within a timeframe the
attached tool was created, based on code from xc_domain_save.
Once the domU touches many pages the reported dirty rate is high, but
after a few seconds the rate drops down from thousands to just a few dozen.

I wonder if the usage of xc_shadow_control is correct. The testing was
done with a xen-4.4 based dom0, I will verify with staging once I find
the time.


Olaf

[-- Attachment #1.1.2: logdirty.c --]
[-- Type: text/x-c, Size: 3002 bytes --]

/* gcc -Wall -o logdirty -O -lxenctrl logdirty.c */
#include <unistd.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <xenctrl.h>
#include <signal.h>

#define PAGE_SHIFT              XC_PAGE_SHIFT
#define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1))
#define NRPAGES(x) (ROUNDUP(x, PAGE_SHIFT) >> PAGE_SHIFT)
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
#define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6)


static unsigned int domid = 0;
static xc_interface *xch;

static unsigned long xdmg(xc_interface *c, unsigned int d)
{
	unsigned long r;
#if XEN_DOMCTL_INTERFACE_VERSION < 0x0b
	r = xc_domain_maximum_gpfn(c, d);
#else
	xen_pfn_t gpfns = 0;
	r = xc_domain_maximum_gpfn(c, d, &gpfns);
#endif
	return r + 1;
}
static void sigint_handler(int sig)
{
	int rc;
	fprintf(stderr, "User aborted\n");
	rc = xc_shadow_control(xch, domid, XEN_DOMCTL_SHADOW_OP_OFF, NULL, 0, NULL, 0, NULL);
        if (rc < 0)
                perror("XEN_DOMCTL_SHADOW_OP_OFF hypercall failed\n");
	exit(1);
}


static inline int bitmap_size(int nr_bits)
{
	int nr_long, nr_bytes;
	nr_long = (nr_bits + BITS_PER_LONG - 1) >> ORDER_LONG;
	nr_bytes = nr_long * sizeof(unsigned long);
	return nr_bytes;
}

int main(int argc, char *argv[])
{
	int rc, ret = 1, i, runs = 42;
	unsigned int lflags;
	xentoollog_level lvl;
	xentoollog_logger *l;
	DECLARE_HYPERCALL_BUFFER(unsigned long, to_skip);
	unsigned long p2m_size;
	xc_shadow_op_stats_t stats;

	errno = EINVAL;
	if (argc > 1)
		domid = atoi(argv[1]);
	if (!domid)
		goto out;

	errno = 0;
	lvl = XTL_DEBUG;
	lflags = XTL_STDIOSTREAM_SHOW_PID | XTL_STDIOSTREAM_HIDE_PROGRESS;
	l = (xentoollog_logger *) xtl_createlogger_stdiostream(stderr, lvl, lflags);
	if (!l)
		goto out;

	xch = xc_interface_open(l, 0, 0);
	if (!xch)
		goto out;

	p2m_size = xdmg(xch, domid);
	if (!p2m_size)
		goto out;

	to_skip = xc_hypercall_buffer_alloc_pages(xch, to_skip, NRPAGES(bitmap_size(p2m_size)));
	if (!to_skip)
		goto out;

	signal(SIGINT, sigint_handler);

	rc = xc_shadow_control(xch, domid, XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY, NULL, 0, NULL, 0, NULL);
	if (rc < 0) {
		rc = xc_shadow_control(xch, domid, XEN_DOMCTL_SHADOW_OP_OFF, NULL, 0, NULL, 0, NULL);
		if (rc < 0)
			goto out;

		rc = xc_shadow_control(xch, domid, XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY, NULL, 0, NULL, 0, NULL);
		if (rc < 0)
			goto out;
	}

	rc = xc_shadow_control(xch, domid, XEN_DOMCTL_SHADOW_OP_CLEAN, NULL, 0, NULL, 0, NULL);
	if (rc < 0)
		goto out;

	for (i = 0; i < runs; i++) {
		sleep(1);
		if (1)
			rc = xc_shadow_control(xch, domid, XEN_DOMCTL_SHADOW_OP_CLEAN, HYPERCALL_BUFFER(to_skip), p2m_size, NULL, 0, &stats);
		if (rc < 0)
			goto out;
		printf("%d: faults= %" PRIu32 " dirty= %" PRIu32 "\n", i, stats.fault_count, stats.dirty_count);
	}
	rc = xc_shadow_control(xch, domid, XEN_DOMCTL_SHADOW_OP_OFF, NULL, 0, NULL, 0, NULL);
	if (rc < 0)
		goto out;
	errno = ret = 0;
      out:
	perror(argv[0]);
	return ret;
}

[-- Attachment #1.1.3: memdirty.c --]
[-- Type: text/x-c, Size: 1180 bytes --]

/* gcc -Wall -o memdirty memdirty.c */
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

static void usage(const char *prog, FILE * out)
{
	fprintf(out, "usage: %s allocsize\n", prog);
	fprintf(out, " allocsize is kbytes, or number[KMGP] (P = pages)\n");
	exit(out == stderr);
}

int main(int argc, char *argv[])
{
	long long kbtotal = 0, pages, i;
	unsigned offset;
	char *mem, *tmp;

	if (argc == 2) {
		char *end = NULL;
		kbtotal = strtoull(argv[1], &end, 0);

		switch (*end) {
		case 'g':
		case 'G':
			kbtotal *= 1024;
		case 'm':
		case 'M':
			kbtotal *= 1024;
		case '\0':
		case 'k':
		case 'K':
			break;
		case 'p':
		case 'P':
			kbtotal *= 4;
			break;
		default:
			usage(argv[0], stderr);
			break;
		}
	}

	if (argc != 2 || kbtotal == 0)
		usage(argv[0], stderr);

	pages = kbtotal / 4;
	errno = 0;
	printf("[%d] allocating %lld kbytes, %lld pages\n", getpid(), kbtotal, pages);
	mem = calloc(pages, 4096);
	perror("calloc");
	if (mem == NULL)
		exit(1);

	offset = 0;
	while (1) {
		for (i = 0; i < pages; i++) {
			tmp = (mem + (i * 4096)) + (offset++ & (4096 - 1));
			*tmp = *tmp + 1;
		}
	}
	return 0;
}

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

[-- Attachment #2: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-03-30 11:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-21  9:50 inaccurate dirty_count from XEN_DOMCTL_SHADOW_OP Olaf Hering
2017-03-22 10:46 ` Olaf Hering
2017-03-22 10:53   ` Andrew Cooper
2017-03-22 10:59   ` Olaf Hering
2017-03-30 11:40     ` Andrew Cooper
2017-03-30 11:50       ` Olaf Hering

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.