Subject: switch_to

From: Philip Blundell <[email-masked]>
Date: Fri, 15 Jan 1999 11:22:16 +0100

Does this seem a reasonable thing to do?  The patch isn't tested but you 
should get the idea.

p.

--- clean/linux/arch/arm/mm/proc-sa110.S	Tue Jan 12 13:48:12 1999
+++ linux/arch/arm/mm/proc-sa110.S	Fri Jan 15 11:20:42 1999
@@ -238,6 +238,7 @@
 		stmfd	sp!, {r4 - r9, fp, lr}		@ Store most regs on stack
 		mrs	ip, cpsr
 		stmfd	sp!, {ip}			@ Save cpsr_SVC
+		ldr	r2, [r0, #TSS_MEMMAP]		@ Get old page tables
 		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
 		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
 		ldr	r0, [r1, #TSK_ADDR_LIMIT]
@@ -246,6 +247,16 @@
 		movne	r0, #DOM_USERDOMAIN
 		mcr	p15, 0, r0, c3, c0		@ Set segment
 		ldr	r0, [r1, #TSS_MEMMAP]		@ Page table pointer
+		/* Flushing the cache is nightmarishly slow, so we take
+		   any excuse to get out of it.  If the old page table
+		   is the same as the new, this is a CLONE_VM relative
+		   of the old task and there is no need to flush.  The
+		   overhead of the tests isn't even on the radar compared to
+		   the cost of the flush itself.  */
+		/* @@ In future we could also check for the new task being
+		   a kernel thread.  */
+		teq	r0, r2				@ Same pagetables?
+		beq	2f
 		ldr	r3, =Lclean_switch
 		ldr	r2, [r3]
 		ands	r2, r2, #1
@@ -262,7 +273,7 @@
 		mcr	p15, 0, r1, c7, c10, 4		@ drain WB
 		mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
 		mcr	p15, 0, r1, c8, c7, 0		@ flush TLBs
-		ldmfd	sp!, {ip}
+2:		ldmfd	sp!, {ip}
 		msr	spsr, ip			@ Save tasks CPSR into SPSR for this return
 		ldmfd	sp!, {r4 - r9, fp, pc}^		@ Load all regs saved previously

unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Fri, 15 Jan 1999 19:22:28 +0000 (GMT)

> +		/* @@ In future we could also check for the new task being

This is no longer an option - the new kcardd keeps the expansion cards
mapped at virtual address 0x03000000 while in a kernel thread, so doing
this will cause problems with this.

kcardd gets around many problems with various expansion cards on Acorn
32-bit platforms.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Fri, 15 Jan 1999 22:56:30 +0100

>this will cause problems with this.

OK, so we can't do it on Acorn platforms.  Others are still OK.

Exactly why does kcardd do this, out of interest?

p.

---

From: Philip Blundell <[email-masked]>
Date: Sat, 16 Jan 1999 10:52:05 +0100

>So that it can access the expansion card ROMs using their loaders to get
>things like Ether addresses out of them, and shut the cards down properly
>when rebooting (so that RISC OS and Linux can re-detect them).

I see.  Does it really need a daemon do do that?  I'd have thought just 
mapping the cards temporarily at startup and again at shutdown would suffice.
Not that a daemon really hurts I suppose.

>(Interestingly, I believe that RiscBSD have to write a new loader for
>each and every card that they support).

I didn't think they used loaders at all actually.  You only really need one 
(as far as I can see) if you have software on the ROM that you want the OS to 
be able to get at without it needing to know how the hardware works.  Since 
with both Linux and RISC OS it's the case that you have to specifically 
compile in the appropriate driver, this isn't much of a win.  You can get the 
card ID data out without the loader should you so desire.

RiscBSD has a generic system of `shutdown hooks' that allow drivers to 
register a routine to be called just before halt or reboot.  This lets you 
turn the cards off again when you need to.

BTW, it occurs to me that even in the presence of kcardd (assuming there's 
only one of it) you can avoid a cache flush on context switch if the *old* 
task rather than the new one is a kernel thread.  Or we could just arrange for 
kcardd not to count as a kernel thread.

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sat, 16 Jan 1999 10:11:01 +0000 (GMT)

Unfortunately, Acorn did not think about 32-bit modes when they designed
RISC OS, so there are a lot of cards out there that will not access their
cards when they're mapped into 0xe0000000.  I used to fix up the problematic
loaders (by re-writing them), but since I receive mails about Linux not
booting and people not appearing to know about the FAQ, I've decided to
go for the option that will allow 99% to work ok, rather than 30% and
the other 60% requiring either blacklisting or replacement loaders to
be written.

With kcardd, it should be able to handle 99% of loaders (since the loaders
/are/ supposed to be OS non-specific), I think that the only ones that
won't work are those which are badly written to use RISC OS SWIs.

---

From: "Neil A. Carson" <[email-masked]>
Date: Sat, 16 Jan 1999 02:39:42 -0800

> each and every card that they support).

Actually, NetBSD ignores loaders completely, mainly because we hardly
ever need to access the ROMs on the cards. Even in the case of reading
an ethernet hardware address, we've not had a problem getting it without
using the loader as all the cards so far supported have had the info in
the first couple of KB. Given the loader does so little, it hardly seems
worth bothering to run it. You need to nkow the h/w to drive it, and a
paging or reset register isn't exactly difficult.

Why bother with loaders, at the expense of thread switch times? On
NetBSD, I shortcut switching between different kernel threads (eg
process reaper) although that patch hasn't been committed yet which I
think is kind-of what Phil suggested.

Just playing devil's :-)

	Regards,

	Neil

---

From: Philip Blundell <[email-masked]>
Date: Sat, 16 Jan 1999 21:50:15 +0100

>However, when you start to think about loadable modules, this argument does
>not count (loaders are required to get at the IP addresses for some netcards, 
>since they're stored in the description string, 

It's scarcely hard to teach the driver how to write to a paging register.

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sat, 16 Jan 1999 21:04:17 +0000 (GMT)

> Not that a daemon really hurts I suppose.

However, when you start to think about loadable modules, this argument does not
count (loaders are required to get at the IP addresses for some netcards, since
they're stored in the description string, which might not be in the first chunk
directory).

> kcardd not to count as a kernel thread.

kcardd could be given a separate set of page tables, which in that case it would
suffice (since mm->pgd != swapper_pg_dir).
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: James Craig <[email-masked]>
Date: Sat, 16 Jan 1999 22:28:59 +0000 (GMT)

> It's scarcely hard to teach the driver how to write to a paging register.
But surely a less elegant solution than a general podule loader handling
system.

--
James Craig <[email-masked]>
            <[email-masked]>

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sat, 16 Jan 1999 23:26:39 +0000 (GMT)

> It's scarcely hard to teach the driver how to write to a paging register.

So rather than have a generic expansion card handler, you'd rather duplicate
code left right and centre to be able to read the cards IDs, the chunk
directories and so forth.

I don't think so.  If you don't like it, complain to what's left of Acorn for
creating such a brain dead spec, and the third party companies for implementing
it.  This is what we've got to work with, and it's worked satisfactorily for
the last 5 years.

The kcardd idea is quite clean, and doesn't cost us a lot.  It also allows these
cards which have wrong IDs on them to work (eg, the PowerROMs).  If you're worried
about the code supplied on expansion cards having trojans in them, I don't think
so.  You've got to trust some non-free software at some point.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Sun, 17 Jan 1999 11:47:39 +0100

>The kcardd idea is quite clean, and doesn't cost us a lot.  It also allows
>these cards which have wrong IDs on them to work (eg, the PowerROMs).  If 
>you're worried about the code supplied on expansion cards having trojans 
>in them, I don't think so.  You've got to trust some non-free software at
>some point.

I think you're the only one who's mentioned trustworthyness of ROMs.  I don't 
have a problem with that.  My gripe about kecardd is just that it seems 
somewhat over-engineered and it increases the memory footprint to no purpose 
on 26-bit machines.  Perhaps the solution is to create a cut-down version of 
the podule support for those systems though, then you could remove a lot of 
the #ifdefs in ecard.c.

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sun, 17 Jan 1999 12:13:09 +0000 (GMT)

Philip Blundell writes:
> My gripe about kecardd is just that it seems somewhat over-engineered and it
> increases the memory footprint to no purpose on 26-bit machines.  Perhaps
> the solution is to create a cut-down version of the podule support for those
> systems though, then you could remove a lot of the #ifdefs in ecard.c.

I'm beginning to wonder if you really have looked at the code at this point.
You mention the #ifdefs, but if you notice what they do, they do do exactly
what you say - produce a cut down ecard.c.

Since kcardd only went in last week, I haven't finished optimising it for
the older machines, and indeed it won't be there for the older machines
once I've finished it.

Anyway, I didn't think that 2.2 was able to run on the old machines with only
4MB any more.
   _____

---

From: Philip Blundell <[email-masked]>
Date: Sun, 17 Jan 1999 13:22:45 +0100

>what you say - produce a cut down ecard.c.

I'm aware of that.

>Anyway, I didn't think that 2.2 was able to run on the old machines with only

It's not precisely luxurious but it runs.  It helps if you teach the console 
driver to grab less than 480k of memory when you're in a smaller mode.  I'm 
still reasonably optimistic of getting it to fly on a 2MB machine, though 1MB 
may be stretching things a little far.

p.

---

From: Philip Blundell <[email-masked]>
Date: Sun, 17 Jan 1999 13:24:36 +0100

>Even 2.0 has problems - a dynamically linked swapon wouldn't run on the
>4MB A5000 I tried it on as it was unable to mmap libc.  I haven't been
>able to experiment further since it's in the UK and I'm not.

Yeah.  You need to hack the kernel to get it to turn swap on before launching 
init.  I guess a swap=.. command line option is what's needed.

p.

---

From: Matthew Wilcox <[email-masked]>
Date: Sun, 17 Jan 1999 14:17:32 +0100

-- 
Matthew Wilcox <[email-masked]>
"I decry the current tendency to seek patents on algorithms.  There are
better ways to earn a living than to prevent other people from making use of
one's contributions to computer science."  -- Donald E. Knuth, TAoCP vol 3
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Tue, 19 Jan 1999 09:55:40 +0100

>paging or reset register isn't exactly difficult.

Yeah, that's my feeling too. 

>think is kind-of what Phil suggested.

Basically.  Since a kernel thread (usually) doesn't have any memory mapping in 
the area normally touched by user tasks, we don't have to worry about cache 
issues.  In fact I've now thought of a way to play things that will hopefully 
allow us to handle the case where a user process is fighting a kernel thread 
for the CPU without any cache flush at all, and the clone() case comes out in 
the wash which is an extra bonus. :-)

Essentially what you do is just to remember the last set of pagetables you 
loaded for a non-kernel thread (having nobbled kecardd such that it doesn't 
count as a kernel thread any more).  If it's the same as the one you're about 
to load in, or if the new task is a kernel thread, you can skip the cache and 
TLB drama.

I'll see if I can come up with a patch later.  By the way, before I send the 
CATS board back, do you guys have any benchmark numbers for NetBSD running on 
one of those?  I'd be interested to see how Linux compares.

p.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Tue, 19 Jan 1999 21:32:13 +0000 (GMT)

> paging or reset register isn't exactly difficult.

Let me clarify a point about the expansion card support: Linux will not use
the loader if it doesn't have to.  ie, if it can find all the information it
requires without loading the loader, then the loader will not be used.

However, if it can't find the information it needs in the first chunk
directory, it will use the loader to access the next chunk directory.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]