- write tons of data to nbd device, data ends up in pagecache
- memory gets low, kswapd wakes up, calls nbd device to actually write
the data
- nbd issues a request, which ends up on the nbd server on the same machine
- the nbd server allocates memory
- memory allocation hangs waiting for kswapd

In other words, it can deadlock only if you are swapping to an nbd
device that is served by nbd-server running on the same machine and
kernel. In the case of a qemu system swapping over nbd to a server on
the host machine, it is the guest kernel that waits on the host kernel
paging the nbd server in from the host's separate swap space, so no
deadlock is possible.

Practice bears this out; if you wanna stress-test it, here's a program
that creates a low memory condition by saturating the VM.

Of course, this has nothing to do with the original patch, which just
lets nbd-server interpret qemu image files ;)

   M
/*
 * thrash.c
 *
 * A standalone Unix command-line program to
 * make the machine thrash, ie go into permanent swapping,
 * by using VM >= RAM size and accessing all pages repeatedly
 *
 * Usage: thrash size
 * where "size" is the number of megabytes to thrash
 * A good choice for N is the number of megabytes of physical RAM
 * that the machine has.
 *
 * Reason:
 * to force a machine to use its swap space,
 * to flush all unused pages out to swap and so free RAM for other purposes
 * or to see how a system behaves under extreme duress.
 *
 * It currently *writes* to all pages, but could be made to read them
 * as an alternative, or as well.
 *
 *	Martin Guy, 9 November 2006
 */

#include <stdlib.h>	/* for exit() */
#include <stdio.h>
#include <unistd.h>	/* for system calls */

main(int argc, char **argv)
{
	int megabytes = 0; /* MB of VM to thrash, from command-line argument.
				* 0 means uninitialised */
	char *buf;	/* Huge VM buffer */
	intptr_t bufsize;	/* Size of buffer in bytes */
	long pagesize;	/* size of VM page */
	int i;		/* index into argv */
	int verbose = 0; /* Print a dot for every pass through VM? */

	pagesize = getpagesize();

	for (i=1; i<argc; i++) {
		if (argv[i][0] == '-') {
			switch (argv[i][1]) {
			case 'v': verbose = 1; break;
			default: goto usage;
			}
		} else if (isdigit(argv[i][0])) {
			megabytes = atoi(argv[i]);
			/* Sanity check comes later */
		} else {
usage:			fputs("Usage: thrash [-v] N\n", stderr);
			fputs("-v\tPrint a dot every time for each pass through memoery\n", stderr);
			fputs("N\tNumber of megabytes of VM to thrash\n", stderr);
			exit(1);
		}
	}

	/* Sanity checks */
	if (megabytes <= 0) goto usage;

	bufsize = (long) megabytes * (long)(1024 * 1024);
	buf = (char *) sbrk(bufsize);
	if (buf == (char *)-1) {
		perror("thrash: Failed to allocate VM");
		exit(1);
	}

	/* Write every page repeatedly */
	for (;;) {
		char *p;
		int i;

		for (p=buf, i=bufsize/pagesize; i>0; p+=pagesize, i--)
			*p=(char) i;
		if (verbose) { putchar('.'); fflush(stdout); }
	}
	/* NOTREACHED */
}
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to