public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Russell King <rmk@arm.linux.org.uk>
To: "Holzrichter, Bruce" <bruce.holzrichter@monster.com>
Cc: "'davem@redhat.com'" <davem@redhat.com>, linux-kernel@vger.kernel.org
Subject: Re: sparc64 pgalloc.h pgd_quicklist question
Date: Sun, 9 Jun 2002 23:36:23 +0100	[thread overview]
Message-ID: <20020609233623.G8761@flint.arm.linux.org.uk> (raw)
In-Reply-To: <61DB42B180EAB34E9D28346C11535A783A78A3@nocmail101.ma.tmpw.net> <20020607091826.A5413@flint.arm.linux.org.uk>

On Fri, Jun 07, 2002 at 09:18:26AM +0100, Russell King wrote:
> On Thu, Jun 06, 2002 at 09:10:40PM -0500, Holzrichter, Bruce wrote:
> > I meant to ask this a little bit back, while I was looking through this
> > code.  In the 2.5 iteration you have for small_page.c your using the
> > next_hash and pprev_hash entries, which no longer are available in the
> > struct page, as far as I have looked, unless your struct page is defined
> > elsewhere, other than linux/mm.h?  Just wondering, as I pull apart the mm
> > code in what time I have looking at this.
> 
> It looks like next_hash and pprev_hash migrated to list.  (I've not
> confirmed that it obeys exactly the same rules yet.)  The solution
> is probably to convert small-page.c to use the list stuff instead.
> 
> If you don't get there before me, I'll probably fix it up this weekend.

Here's a patch that should be applied on top of the existing small_page.c
I've not tested it past the "does it compile" stage, so beware.

(Since mach-arc stuff is falling into disrepair, this code will probably
get removed from Linus' tree soon.)

--- orig/arch/arm/mach-arc/small_page.c	Mon May 13 10:48:07 2002
+++ linux/arch/arm/mach-arc/small_page.c	Sun Jun  9 23:32:42 2002
@@ -50,7 +50,7 @@
  */
 
 struct order {
-	struct page *queue;
+	struct list_head queue;
 	unsigned int mask;		/* (1 << shift) - 1		*/
 	unsigned int shift;		/* (1 << shift) size of page	*/
 	unsigned int block_mask;	/* nr_blocks - 1		*/
@@ -60,10 +60,10 @@
 
 static struct order orders[] = {
 #if PAGE_SIZE == 4096
-	{ NULL, 2047, 11,  1, 0x00000003 }
+	{ LIST_HEAD_INIT(orders[0].queue), 2047, 11,  1, 0x00000003 }
 #elif PAGE_SIZE == 32768
-	{ NULL, 2047, 11, 15, 0x0000ffff },
-	{ NULL, 8191, 13,  3, 0x0000000f }
+	{ LIST_HEAD_INIT(orders[0].queue), 2047, 11, 15, 0x0000ffff },
+	{ LIST_HEAD_INIT(orders[1].queue), 8191, 13,  3, 0x0000000f }
 #else
 #error unsupported page size
 #endif
@@ -75,70 +75,49 @@
 
 static spinlock_t small_page_lock = SPIN_LOCK_UNLOCKED;
 
-static void add_page_to_queue(struct page *page, struct page **p)
-{
-#ifdef PEDANTIC
-	if (page->pprev_hash)
-		PAGE_BUG(page);
-#endif
-	page->next_hash = *p;
-	if (*p)
-		(*p)->pprev_hash = &page->next_hash;
-	*p = page;
-	page->pprev_hash = p;
-}
-
-static void remove_page_from_queue(struct page *page)
-{
-	if (page->pprev_hash) {
-		if (page->next_hash)
-			page->next_hash->pprev_hash = page->pprev_hash;
-		*page->pprev_hash = page->next_hash;
-		page->pprev_hash = NULL;
-	}
-}
-
 static unsigned long __get_small_page(int priority, struct order *order)
 {
 	unsigned long flags;
 	struct page *page;
 	int offset;
 
-	if (!order->queue)
-		goto need_new_page;
+	do {
+		spin_lock_irqsave(&small_page_lock, flags);
+
+		if (list_empty(&order->queue))
+			goto need_new_page;
 
-	spin_lock_irqsave(&small_page_lock, flags);
-	page = order->queue;
+		page = list_entry(order->queue.next, struct page, list);
 again:
 #ifdef PEDANTIC
-	if (USED_MAP(page) & ~order->all_used)
-		PAGE_BUG(page);
+		if (USED_MAP(page) & ~order->all_used)
+			PAGE_BUG(page);
 #endif
-	offset = ffz(USED_MAP(page));
-	SET_USED(page, offset);
-	if (USED_MAP(page) == order->all_used)
-		remove_page_from_queue(page);
-	spin_unlock_irqrestore(&small_page_lock, flags);
+		offset = ffz(USED_MAP(page));
+		SET_USED(page, offset);
+		if (USED_MAP(page) == order->all_used)
+			list_del_init(&page->list);
+		spin_unlock_irqrestore(&small_page_lock, flags);
 
-	return (unsigned long) page_address(page) + (offset << order->shift);
+		return (unsigned long) page_address(page) + (offset << order->shift);
 
 need_new_page:
-	page = alloc_page(priority);
+		spin_unlock_irqrestore(&small_page_lock, flags);
+		page = alloc_page(priority);
+		spin_lock_irqsave(&small_page_lock, flags);
+
+		if (list_empty(&order->queue)) {
+			if (!page)
+				goto no_page;
+			SetPageReserved(page);
+			USED_MAP(page) = 0;
+			list_add(&page->list, &order->queue);
+			goto again;
+		}
 
-	spin_lock_irqsave(&small_page_lock, flags);
-	if (!order->queue) {
-		if (!page)
-			goto no_page;
-		SetPageReserved(page);
-		USED_MAP(page) = 0;
-		cli();
-		add_page_to_queue(page, &order->queue);
-	} else {
+		spin_unlock_irqrestore(&small_page_lock, flags);
 		__free_page(page);
-		cli();
-		page = order->queue;
-	}
-	goto again;
+	} while (1);
 
 no_page:
 	spin_unlock_irqrestore(&small_page_lock, flags);
@@ -173,7 +152,7 @@
 		spin_lock_irqsave(&small_page_lock, flags);
 
 		if (USED_MAP(page) == order->all_used)
-			add_page_to_queue(page, &order->queue);
+			list_add(&page->list, &order->queue);
 
 		if (!TEST_AND_CLEAR_USED(page, spage))
 			goto already_free;
@@ -189,7 +168,7 @@
 	/*
 	 * unlink the page from the small page queue and free it
 	 */
-	remove_page_from_queue(page);
+	list_del_init(&page->list);
 	spin_unlock_irqrestore(&small_page_lock, flags);
 	ClearPageReserved(page);
 	__free_page(page);

-- 
Russell King (rmk@arm.linux.org.uk)                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html


  reply	other threads:[~2002-06-09 22:36 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-06-07  2:10 sparc64 pgalloc.h pgd_quicklist question Holzrichter, Bruce
2002-06-07  8:18 ` Russell King
2002-06-09 22:36   ` Russell King [this message]
     [not found] <61DB42B180EAB34E9D28346C11535A783A775C@nocmail101.ma.tmpw.net>
2002-05-24 16:05 ` David S. Miller
2002-05-24 16:28   ` Russell King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020609233623.G8761@flint.arm.linux.org.uk \
    --to=rmk@arm.linux.org.uk \
    --cc=bruce.holzrichter@monster.com \
    --cc=davem@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox