Esempio n. 1
0
/*
 * Invoked by the selfballoon worker thread, uses current number of pages
 * in frontswap (frontswap_curr_pages()), previous status, and control
 * values (hysteresis and inertia) to determine if frontswap should be
 * shrunk and what the new frontswap size should be.  Note that
 * frontswap_shrink is essentially a partial swapoff that immediately
 * transfers pages from the "swap device" (frontswap) back into kernel
 * RAM; despite the name, frontswap "shrinking" is very different from
 * the "shrinker" interface used by the kernel MM subsystem to reclaim
 * memory.
 */
static void frontswap_selfshrink(void)
{
	static unsigned long cur_frontswap_pages;
	static unsigned long last_frontswap_pages;
	static unsigned long tgt_frontswap_pages;

	last_frontswap_pages = cur_frontswap_pages;
	cur_frontswap_pages = frontswap_curr_pages();
	if (!cur_frontswap_pages ||
			(cur_frontswap_pages > last_frontswap_pages)) {
		frontswap_inertia_counter = frontswap_inertia;
		return;
	}
	if (frontswap_inertia_counter && --frontswap_inertia_counter)
		return;
	if (cur_frontswap_pages <= frontswap_hysteresis)
		tgt_frontswap_pages = 0;
	else
		tgt_frontswap_pages = cur_frontswap_pages -
			(cur_frontswap_pages / frontswap_hysteresis);
	frontswap_shrink(tgt_frontswap_pages);
}
Esempio n. 2
0
/*
 * Use current balloon size, the goal (vm_committed_as), and hysteresis
 * parameters to set a new target balloon size
 */
static void selfballoon_process(struct work_struct *work)
{
	int cur_pages, goal_pages, tgt_pages;
	bool reset_timer = false;

	if (kvm_selfballooning_enabled) {
		cur_pages = vbal->num_pages;
		tgt_pages = cur_pages; /* default is no change */
		goal_pages = totalram_pages + cur_pages -
			percpu_counter_read_positive(&vm_committed_as);
#ifdef CONFIG_FRONTSWAP
		/* allow space for frontswap pages to be repatriated */
		if (frontswap_selfshrinking && frontswap_enabled)
			goal_pages += frontswap_curr_pages();
#endif
		if (cur_pages > goal_pages)
			tgt_pages = cur_pages -
				((cur_pages - goal_pages) /
				  selfballoon_downhysteresis);
		else if (cur_pages < goal_pages)
			tgt_pages = cur_pages +
				((goal_pages - cur_pages) /
				  selfballoon_uphysteresis);
		/* else if cur_pages == goal_pages, no change */
		selfballoon_target(vbal, (unsigned int)(tgt_pages));
		reset_timer = true;
	}
#ifdef CONFIG_FRONTSWAP
	if (frontswap_selfshrinking && frontswap_enabled) {
		frontswap_selfshrink();
		reset_timer = true;
	}
#endif
	if (reset_timer)
		schedule_delayed_work(&selfballoon_worker,
			selfballoon_interval * HZ);
}
Esempio n. 3
0
static ssize_t curr_pages_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", frontswap_curr_pages());
}