linux/drivers/misc/vmw_balloon.c
/*
 * Inflate the balloon towards its target size. Note that we try to limit
 * the rate of allocation to make sure we are not choking the rest of the
 * system.
 */
Inflate the balloon towards its target size. Note that we try to limit
the rate of allocation to make sure we are not choking the rest of the
system.
Inflate the balloon towards its target size . Note that we try to limit the rate of allocation to make sure we are not choking the rest of the system .
static void vmballoon_inflate(struct vmballoon *b)
{
	unsigned int num_pages = 0;
	int error = 0;
	gfp_t flags = VMW_PAGE_ALLOC_NOSLEEP;
	bool is_2m_pages;
	pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
	is_2m_pages = b->supported_page_sizes == VMW_BALLOON_NUM_PAGE_SIZES;
	pr_debug("%s - goal: %d",  __func__, b->target - b->size);
	while (!b->reset_required &&
		b->size + num_pages * vmballoon_page_size(is_2m_pages)
		< b->target) {
		struct page *page;
		if (flags == VMW_PAGE_ALLOC_NOSLEEP)
			STATS_INC(b->stats.alloc[is_2m_pages]);
		else
			STATS_INC(b->stats.sleep_alloc);
		page = vmballoon_alloc_page(flags, is_2m_pages);
		if (!page) {
			STATS_INC(b->stats.alloc_fail[is_2m_pages]);
			if (is_2m_pages) {
				b->ops->lock(b, num_pages, true, &b->target);
				num_pages = 0;
				is_2m_pages = false;
				continue;
			}
			if (flags == VMW_PAGE_ALLOC_CANSLEEP) {
				STATS_INC(b->stats.sleep_alloc_fail);
				break;
			}
			flags = VMW_PAGE_ALLOC_CANSLEEP;
			continue;
		}
		b->ops->add_page(b, num_pages++, page);
		if (num_pages == b->batch_max_pages) {
			error = b->ops->lock(b, num_pages, is_2m_pages,
					&b->target);
			num_pages = 0;
			if (error)
				break;
		}
		cond_resched();
	}
	if (num_pages > 0)
		b->ops->lock(b, num_pages, is_2m_pages, &b->target);
	vmballoon_release_refused_pages(b, true);
	vmballoon_release_refused_pages(b, false);
}
static void vmballoon_inflate ( struct vmballoon * b ) { unsigned int num_pages = 0 ; int error = 0 ; gfp_t flags = VMW_PAGE_ALLOC_NOSLEEP ; bool is_2m_pages ; pr_debug ( " \n " , __func__ , b -> size , b -> target ) ; is_2m_pages = b -> supported_page_sizes == VMW_BALLOON_NUM_PAGE_SIZES ; pr_debug ( " " , __func__ , b -> target - b -> size ) ; while ( ! b -> reset_required && b -> size + num_pages * vmballoon_page_size ( is_2m_pages ) < b -> target ) { struct page * page ; if ( flags == VMW_PAGE_ALLOC_NOSLEEP ) STATS_INC ( b -> stats . alloc [ is_2m_pages ] ) ; else STATS_INC ( b -> stats . sleep_alloc ) ; page = vmballoon_alloc_page ( flags , is_2m_pages ) ; if ( ! page ) { STATS_INC ( b -> stats . alloc_fail [ is_2m_pages ] ) ; if ( is_2m_pages ) { b -> ops -> lock ( b , num_pages , true , & b -> target ) ; num_pages = 0 ; is_2m_pages = false ; continue ; } if ( flags == VMW_PAGE_ALLOC_CANSLEEP ) { STATS_INC ( b -> stats . sleep_alloc_fail ) ; break ; } flags = VMW_PAGE_ALLOC_CANSLEEP ; continue ; } b -> ops -> add_page ( b , num_pages ++ , page ) ; if ( num_pages == b -> batch_max_pages ) { error = b -> ops -> lock ( b , num_pages , is_2m_pages , & b -> target ) ; num_pages = 0 ; if ( error ) break ; } cond_resched ( ) ; } if ( num_pages > 0 ) b -> ops -> lock ( b , num_pages , is_2m_pages , & b -> target ) ; vmballoon_release_refused_pages ( b , true ) ; vmballoon_release_refused_pages ( b , false ) ; }
Inflate the balloon towards its target size.
Inflate the balloon towards its target size .
/*
	 * First try NOSLEEP page allocations to inflate balloon.
	 *
	 * If we do not throttle nosleep allocations, we can drain all
	 * free pages in the guest quickly (if the balloon target is high).
	 * As a side-effect, draining free pages helps to inform (force)
	 * the guest to start swapping if balloon target is not met yet,
	 * which is a desired behavior. However, balloon driver can consume
	 * all available CPU cycles if too many pages are allocated in a
	 * second. Therefore, we throttle nosleep allocations even when
	 * the guest is not under memory pressure. OTOH, if we have already
	 * predicted that the guest is under memory pressure, then we
	 * slowdown page allocations considerably.
	 */ /*
	 * Start with no sleep allocation rate which may be higher
	 * than sleeping allocation rate.
	 */ /*
				 * ignore errors from locking as we now switch
				 * to 4k pages and we might get different
				 * errors.
				 */ /*
				 * CANSLEEP page allocation failed, so guest
				 * is under severe memory pressure. We just log
				 * the event, but do not stop the inflation
				 * due to its negative impact on performance.
				 */ /*
			 * NOSLEEP page allocation failed, so the guest is
			 * under memory pressure. Slowing down page alloctions
			 * seems to be reasonable, but doing so might actually
			 * cause the hypervisor to throttle us down, resulting
			 * in degraded performance. We will count on the
			 * scheduler and standard memory management mechanisms
			 * for now.
			 */