lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 12 Sep 2006 16:07:03 +0800
From:	Aubrey <aubreylee@...il.com>
To:	"Nick Piggin" <nickpiggin@...oo.com.au>
Cc:	"David Howells" <dhowells@...hat.com>,
	linux-kernel@...r.kernel.org, mpm@...enic.com, davidm@...pgear.com,
	gerg@...pgear.com
Subject: Re: kernel BUGs when removing largish files with the SLOB allocator

On 9/6/06, Nick Piggin <nickpiggin@...oo.com.au> wrote:
> Aubrey wrote:
>
> > Yeah, I agree with most of your opinion. Using PG_slab is really a
> > quickest way to determine the size of the object. But I think using a
> > flag named "PG_slab" on a memory algorithm named "slob" seems not
> > reasonable. It may confuse the people who start to read the kernel
> > source code. So I'm writing to ask if there is a better solution to
> > fix the issue.
>
>
> No, confusing would be a "slab replacement" that doesn't provide the same
> API as slab and thus requires users to use ifdefs.
>
> I've already suggested exact same thing as David in the exact same situation
> about 6 months ago. It is the right way to go.

OK. Here is the patch and work properly on my side.
Welcome any suggestions and comments.

Thanks,
-Aubrey
=================================================================
diff --git a/mm/slob.c b/mm/slob.c
index 7b52b20..18ed170 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -109,6 +109,7 @@ static void *slob_alloc(size_t size, gfp

 			slob_free(cur, PAGE_SIZE);
 			spin_lock_irqsave(&slob_lock, flags);
+			SetPageSlab(virt_to_page(cur));
 			cur = slobfree;
 		}
 	}
@@ -162,6 +163,8 @@ void *kmalloc(size_t size, gfp_t gfp)
 	slob_t *m;
 	bigblock_t *bb;
 	unsigned long flags;
+	int i;
+	struct page *page;

 	if (size < PAGE_SIZE - SLOB_UNIT) {
 		m = slob_alloc(size + SLOB_UNIT, gfp, 0);
@@ -173,12 +176,17 @@ void *kmalloc(size_t size, gfp_t gfp)
 		return 0;

 	bb->order = find_order(size);
-	bb->pages = (void *)__get_free_pages(gfp, bb->order);
+	page = alloc_pages(gfp, bb->order);
+	bb->pages = (void *)page_address(page);

 	if (bb->pages) {
 		spin_lock_irqsave(&block_lock, flags);
 		bb->next = bigblocks;
 		bigblocks = bb;
+		for (i = 0; i < (1 << bb->order); i++) {
+			SetPageSlab(page);
+			page++;
+		}
 		spin_unlock_irqrestore(&block_lock, flags);
 		return bb->pages;
 	}
@@ -202,8 +210,16 @@ void kfree(const void *block)
 		spin_lock_irqsave(&block_lock, flags);
 		for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) {
 			if (bb->pages == block) {
+				struct page *page = virt_to_page(bb->pages);
+				int i;
+
 				*last = bb->next;
 				spin_unlock_irqrestore(&block_lock, flags);
+				for (i = 0; i < (1 << bb->order); i++) {
+					if (!TestClearPageSlab(page))
+						BUG();
+					page++;
+				}
 				free_pages((unsigned long)block, bb->order);
 				slob_free(bb, sizeof(bigblock_t));
 				return;
@@ -332,10 +348,12 @@ static struct timer_list slob_timer = TI

 void kmem_cache_init(void)
 {
+#if 0
 	void *p = slob_alloc(PAGE_SIZE, 0, PAGE_SIZE-1);

 	if (p)
 		free_page((unsigned long)p);
+#endif

 	mod_timer(&slob_timer, jiffies + HZ);
 }
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ