Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4477e90 authored by Nitin Gupta's avatar Nitin Gupta Committed by Greg Kroah-Hartman
Browse files

staging: zsmalloc: fix memory leak



This patch fixes a memory leak in zsmalloc where the first
subpage of each zspage is leaked when the zspage is freed.

Signed-off-by: default avatarNitin Gupta <ngupta@vflare.org>
Acked-by: default avatarSeth Jennings <sjenning@linux.vnet.ibm.com>
Acked-by: default avatarDan Magenheimer <dan.magenheimer@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3fd654c2
Loading
Loading
Loading
Loading
+18 −12
Original line number Original line Diff line number Diff line
@@ -267,33 +267,39 @@ static unsigned long obj_idx_to_offset(struct page *page,
	return off + obj_idx * class_size;
	return off + obj_idx * class_size;
}
}


static void reset_page(struct page *page)
{
	clear_bit(PG_private, &page->flags);
	clear_bit(PG_private_2, &page->flags);
	set_page_private(page, 0);
	page->mapping = NULL;
	page->freelist = NULL;
	reset_page_mapcount(page);
}

static void free_zspage(struct page *first_page)
static void free_zspage(struct page *first_page)
{
{
	struct page *nextp, *tmp;
	struct page *nextp, *tmp, *head_extra;


	BUG_ON(!is_first_page(first_page));
	BUG_ON(!is_first_page(first_page));
	BUG_ON(first_page->inuse);
	BUG_ON(first_page->inuse);


	nextp = (struct page *)page_private(first_page);
	head_extra = (struct page *)page_private(first_page);


	clear_bit(PG_private, &first_page->flags);
	reset_page(first_page);
	clear_bit(PG_private_2, &first_page->flags);
	set_page_private(first_page, 0);
	first_page->mapping = NULL;
	first_page->freelist = NULL;
	reset_page_mapcount(first_page);
	__free_page(first_page);
	__free_page(first_page);


	/* zspage with only 1 system page */
	/* zspage with only 1 system page */
	if (!nextp)
	if (!head_extra)
		return;
		return;


	list_for_each_entry_safe(nextp, tmp, &nextp->lru, lru) {
	list_for_each_entry_safe(nextp, tmp, &head_extra->lru, lru) {
		list_del(&nextp->lru);
		list_del(&nextp->lru);
		clear_bit(PG_private_2, &nextp->flags);
		reset_page(nextp);
		nextp->index = 0;
		__free_page(nextp);
		__free_page(nextp);
	}
	}
	reset_page(head_extra);
	__free_page(head_extra);
}
}


/* Initialize a newly allocated zspage */
/* Initialize a newly allocated zspage */