aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNitin Gupta <ngupta@vflare.org>2012-04-02 10:13:56 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-10 12:18:59 -0400
commitf4477e90b3ea4c40466e8f418cf41a17aef09192 (patch)
tree7cba846e1a7a317bc3949b4063677942c614c150
parent3fd654c22c7b002e8681accaed50a6d46656d815 (diff)
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: Nitin Gupta <ngupta@vflare.org> Acked-by: Seth Jennings <sjenning@linux.vnet.ibm.com> Acked-by: Dan Magenheimer <dan.magenheimer@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/zsmalloc/zsmalloc-main.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c
index 09caa4f2687e..917461c66014 100644
--- a/drivers/staging/zsmalloc/zsmalloc-main.c
+++ b/drivers/staging/zsmalloc/zsmalloc-main.c
@@ -267,33 +267,39 @@ static unsigned long obj_idx_to_offset(struct page *page,
267 return off + obj_idx * class_size; 267 return off + obj_idx * class_size;
268} 268}
269 269
270static void reset_page(struct page *page)
271{
272 clear_bit(PG_private, &page->flags);
273 clear_bit(PG_private_2, &page->flags);
274 set_page_private(page, 0);
275 page->mapping = NULL;
276 page->freelist = NULL;
277 reset_page_mapcount(page);
278}
279
270static void free_zspage(struct page *first_page) 280static void free_zspage(struct page *first_page)
271{ 281{
272 struct page *nextp, *tmp; 282 struct page *nextp, *tmp, *head_extra;
273 283
274 BUG_ON(!is_first_page(first_page)); 284 BUG_ON(!is_first_page(first_page));
275 BUG_ON(first_page->inuse); 285 BUG_ON(first_page->inuse);
276 286
277 nextp = (struct page *)page_private(first_page); 287 head_extra = (struct page *)page_private(first_page);
278 288
279 clear_bit(PG_private, &first_page->flags); 289 reset_page(first_page);
280 clear_bit(PG_private_2, &first_page->flags);
281 set_page_private(first_page, 0);
282 first_page->mapping = NULL;
283 first_page->freelist = NULL;
284 reset_page_mapcount(first_page);
285 __free_page(first_page); 290 __free_page(first_page);
286 291
287 /* zspage with only 1 system page */ 292 /* zspage with only 1 system page */
288 if (!nextp) 293 if (!head_extra)
289 return; 294 return;
290 295
291 list_for_each_entry_safe(nextp, tmp, &nextp->lru, lru) { 296 list_for_each_entry_safe(nextp, tmp, &head_extra->lru, lru) {
292 list_del(&nextp->lru); 297 list_del(&nextp->lru);
293 clear_bit(PG_private_2, &nextp->flags); 298 reset_page(nextp);
294 nextp->index = 0;
295 __free_page(nextp); 299 __free_page(nextp);
296 } 300 }
301 reset_page(head_extra);
302 __free_page(head_extra);
297} 303}
298 304
299/* Initialize a newly allocated zspage */ 305/* Initialize a newly allocated zspage */