/* memhog.c - DF-3194 amplifier: perpetual guest memory pressure.
 *
 * Cycling allocation+touch+free of a large chunk keeps the VM subsystem in
 * constant reclaim.  Under this pressure the M_WAITOK allocations inside
 * nfs_nget()'s creation phase (kmalloc_obj of the nfsnode at :160, and
 * allocvnode() inside getnewvnode() at :163) can block for milliseconds
 * while holding nfsnhash_lock but NOT yet having inserted the node.
 *
 * During such a block the racing thread's LK_SLEEPFAIL retry loop
 * (lockmgr fails -> goto loop -> rescan) repeatedly rescans the bucket;
 * when the blocked creator finally resumes and LIST_INSERT_HEAD()s its
 * node mid-rescan (cursor already past the head), the retrying thread's
 * rescan misses it, its next lockmgr() acquires without sleeping (the
 * creator released), and its duplicate-validation loop
 * (sys/vfs/nfs/nfs_node.c:189-202) finds the creator's node ->
 * vx_put(fresh VNON vnode) -> nfs_inactive(v_data == NULL) -> panic.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define CHUNK (300u << 20)

int
main(void)
{
	char *p;
	size_t i;

	for (;;) {
		p = malloc(CHUNK);
		if (p) {
			for (i = 0; i < CHUNK; i += 4096)
				p[i] = 1;
			free(p);
		}
		usleep(1000);
	}
	return 0;
}
