linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Ryan Nielsen <ran@krazynet.com>
To: Troy Benjegerdes <hozer@drgw.net>
Cc: linuxppc-dev@lists.linuxppc.org
Subject: Re: Linux-2.2.0-pre5 SMP broken on PReP?
Date: Mon, 11 Jan 1999 04:26:11 -0800	[thread overview]
Message-ID: <19990111042611.A152@gondolin> (raw)
In-Reply-To: <Pine.LNX.4.04.9901071243090.32305-100000@narn.local.drgw.net>; from Troy Benjegerdes on Thu, Jan 07, 1999 at 12:55:22PM -0600


On Thu, Jan 07, 1999 at 12:55:22 -0600, Troy Benjegerdes wrote:
> 
> After working with 2.1.132 for awhile, I decided it was time to try
> Linus's 2.2.0-pre5, however I haven't been able to successfully boot with
> it. I have tweaked code and tried various revisions includeing pre1 and
> pre4 (pre1 wouldn't compile).
> 
> I have been getting crashes in the ncr53c8xx driver, but the dump doesn't
> seem to be providing valid information.

it is crashing in kswapd, not the ncr driver.

I got pre6 to work by reverse-patching the kswapd part of mm/vmscan.c down to pre4
this is only needed for SMP...
--- vmscan.c	Mon Jan 11 03:50:23 1999
+++ vmscan.c.works	Mon Jan 11 03:41:35 1999
@@ -20,6 +20,13 @@
 
 #include <asm/pgtable.h>
 
+/* 
+ * The wait queue for waking up the pageout daemon:
+ */
+static struct task_struct * kswapd_task = NULL;
+
+static void init_swap_timer(void);
+
 /*
  * The swap-out functions return 1 if they successfully
  * threw something out, and we got a free page. It returns
@@ -385,36 +392,71 @@
        printk ("Starting kswapd v%.*s\n", i, s);
 }
 
+#define free_memory(fn) \
+	count++; do { if (!--count) goto done; } while (fn)
+
+static int kswapd_free_pages(int kswapd_state)
+{
+	unsigned long end_time;
+
+	/* Always trim SLAB caches when memory gets low. */
+	kmem_cache_reap(0);
+
+	/* max one hundreth of a second */
+	end_time = jiffies + (HZ-1)/100;
+	do {
+		int priority = 8;
+		int count = pager_daemon.swap_cluster;
+
+		switch (kswapd_state) {
+			do {
+			default:
+				free_memory(shrink_mmap(priority, 0));
+				free_memory(swap_out(priority, 0));
+				kswapd_state++;
+			case 1:
+				free_memory(shm_swap(priority, 0));
+				shrink_dcache_memory(priority, 0);
+				kswapd_state = 0;
+			} while (--priority >= 0);
+			return kswapd_state;
+		}
+done:
+		if (nr_free_pages > freepages.high + pager_daemon.swap_cluster)
+			break;
+	} while (time_before_eq(jiffies,end_time));
+	return kswapd_state;
+}
+
 /*
- * The background pageout daemon, started as a kernel thread
- * from the init process. 
- *
- * This basically executes once a second, trickling out pages
- * so that we have _some_ free memory available even if there
- * is no other activity that frees anything up. This is needed
- * for things like routing etc, where we otherwise might have
- * all activity going on in asynchronous contexts that cannot
- * page things out.
- *
- * If there are applications that are active memory-allocators
- * (most normal use), this basically shouldn't matter.
+ * The background pageout daemon.
+ * Started as a kernel thread from the init process.
  */
 int kswapd(void *unused)
 {
 	current->session = 1;
 	current->pgrp = 1;
 	strcpy(current->comm, "kswapd");
+	sigfillset(&current->blocked);
+	
+	/*
+	 *	As a kernel thread we want to tamper with system buffers
+	 *	and other internals and thus be subject to the SMP locking
+	 *	rules. (On a uniprocessor box this does nothing).
+	 */
+	lock_kernel();
 
 	/*
-	 * Hey, if somebody wants to kill us, be our guest. 
-	 * Don't come running to mama if things don't work.
+	 * Set the base priority to something smaller than a
+	 * regular process. We will scale up the priority
+	 * dynamically depending on how much memory we need.
 	 */
-	siginitsetinv(&current->blocked, sigmask(SIGKILL));
-	
+	current->priority = (DEF_PRIORITY * 2) / 3;
+
 	/*
 	 * Tell the memory management that we're a "memory allocator",
 	 * and that if we need more memory we should get access to it
-	 * regardless (see "__get_free_pages()"). "kswapd" should
+	 * regardless (see "try_to_free_pages()"). "kswapd" should
 	 * never get caught in the normal page freeing logic.
 	 *
 	 * (Kswapd normally doesn't need memory anyway, but sometimes
@@ -425,23 +467,21 @@
 	 */
 	current->flags |= PF_MEMALLOC;
 
+	init_swap_timer();
+	kswapd_task = current;
 	while (1) {
-		if (signal_pending(current))
-			break;
+		int state = 0;
+
 		current->state = TASK_INTERRUPTIBLE;
+		flush_signals(current);
 		run_task_queue(&tq_disk);
-		schedule_timeout(HZ);
-
-		/*
-		 * kswapd isn't even meant to keep up with anything,
-		 * so just a few pages per second is plenty: the only
-		 * point is to make sure that the system doesn't stay
-		 * forever in a really bad memory squeeze.
-		 */
-		if (nr_free_pages < freepages.high)
-			try_to_free_pages(0, 16);
+		schedule();
+		swapstats.wakeups++;
+		state = kswapd_free_pages(state);
 	}
-
+	/* As if we could ever get here - maybe we want to make this killable */
+	kswapd_task = NULL;
+	unlock_kernel();
 	return 0;
 }
 
@@ -488,4 +528,73 @@
 	unlock_kernel();
 
 	return priority >= 0;
+}
+
+/*
+ * Wake up kswapd according to the priority
+ *	0 - no wakeup
+ *	1 - wake up as a low-priority process
+ *	2 - wake up as a normal process
+ *	3 - wake up as an almost real-time process
+ *
+ * This plays mind-games with the "goodness()"
+ * function in kernel/sched.c.
+ */
+static inline void kswapd_wakeup(struct task_struct *p, int priority)
+{
+	if (priority) {
+		p->counter = p->priority << priority;
+		wake_up_process(p);
+	}
+}
+
+/* 
+ * The swap_tick function gets called on every clock tick.
+ */
+void swap_tick(void)
+{
+	struct task_struct *p = kswapd_task;
+
+	/*
+	 * Only bother to try to wake kswapd up
+	 * if the task exists and can be woken.
+	 */
+	if (p && (p->state & TASK_INTERRUPTIBLE)) {
+		unsigned int pages;
+		int want_wakeup;
+
+		/*
+		 * Schedule for wakeup if there isn't lots
+		 * of free memory or if there is too much
+		 * of it used for buffers or pgcache.
+		 *
+		 * "want_wakeup" is our priority: 0 means
+		 * not to wake anything up, while 3 means
+		 * that we'd better give kswapd a realtime
+		 * priority.
+		 */
+		want_wakeup = 0;
+		pages = nr_free_pages;
+		if (pages < freepages.high)
+			want_wakeup = 1;
+		if (pages < freepages.low)
+			want_wakeup = 2;
+		if (pages < freepages.min)
+			want_wakeup = 3;
+	
+		kswapd_wakeup(p,want_wakeup);
+	}
+
+	timer_active |= (1<<SWAP_TIMER);
+}
+
+/* 
+ * Initialise the swap timer
+ */
+
+void init_swap_timer(void)
+{
+	timer_table[SWAP_TIMER].expires = jiffies;
+	timer_table[SWAP_TIMER].fn = swap_tick;
+	timer_active |= (1<<SWAP_TIMER);
 }

[[ This message was sent via the linuxppc-dev mailing list. Replies are ]]
[[ not forced back to the list, so be sure to  Cc linuxppc-dev  if your ]]
[[ reply is of general interest. To unsubscribe from linuxppc-dev, send ]]
[[ the message 'unsubscribe' to linuxppc-dev-request@lists.linuxppc.org ]]

  reply	other threads:[~1999-01-11 12:26 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-01-07 18:55 Linux-2.2.0-pre5 SMP broken on PReP? Troy Benjegerdes
1999-01-11 12:26 ` Ryan Nielsen [this message]
1999-01-11 16:29   ` Benjamin Herrenschmidt
1999-01-12  2:43     ` Ryan Nielsen
1999-01-11 16:54   ` Troy Benjegerdes

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=19990111042611.A152@gondolin \
    --to=ran@krazynet.com \
    --cc=hozer@drgw.net \
    --cc=linuxppc-dev@lists.linuxppc.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;
as well as URLs for NNTP newsgroup(s).