Subject: system call changes

From: Philip Blundell <[email-masked]>
Date: Sun, 27 Feb 2000 18:19:41 +0000

Currently the system call entry path is set up to directly handle functions 
with up to six arguments.  This is wasteful because there is only one, 
comparatively rare, system call that actually uses all six arguments; all 
the others are forced to push a useless word onto the stack.

This patch reworks things so that only a single word of arguments is pushed in 
the standard entry veneer; sys_mmap2 is implemented in assembler so it can 
sort its own arguments out.  The other place that has to change is 
sys_syscall, which fortuitously ends up a cycle or two faster as well.

I'd be interested to hear thoughts on this.

PATCH FOLLOWS

--- rmk/linux/arch/arm/kernel/entry-common.S	Sun Feb 20 14:10:43 2000
+++ armlinux/arch/arm/kernel/entry-common.S	Sun Feb 27 18:03:26 2000
@@ -4,16 +4,6 @@
  */
 
 #define S_OFF		8
-#define SYSCALL_REGS	r4, r5
-
-/*
- * Define to favour ARM8, ARM9 and StrongARM cpus.  This says that it is
- * cheaper to use two LDR instructions than a two-register LDM, if the
- * latter would entail calculating an address specially.
- */
-#if defined(CONFIG_CPU_SA110)
-#define HARVARD_CACHE
-#endif
 
 		.macro	get_softirq, rd
 #ifdef __SMP__
@@ -95,9 +85,7 @@
 #endif
 		enable_irqs ip
 
-		stmdb	sp!, {SYSCALL_REGS}	@ new style: (r0 = arg1, r4 = arg5, r5 = arg6)
-						@ Note that we dont have to handle
-						@ sys_syscalls arg7 here
+		str	r4, [sp, #-S_OFF]!	@ push fifth arg
 		adrsvc	al, lr, fast_syscall_return
 
 		bic	scno, scno, #0xff000000	@ mask off SWI op-code
@@ -141,10 +129,11 @@
 		b	SYMBOL_NAME(deferred)
 
 		.align	5
-
+		.type	__softirq_state, %object
 __softirq_state:
 		.word	SYMBOL_NAME(softirq_state)
 
+		.type	sys_call_table, %object
 ENTRY(sys_call_table)
 #include "calls.S"
 
@@ -153,15 +142,17 @@
  */
 @ r0 = syscall number
 @ r5 = syscall table
+		.type	sys_syscall, %function
 SYMBOL_NAME(sys_syscall):
 		eor	scno, r0, #OS_NUMBER << 20
 		cmp	scno, #NR_syscalls	@ check range
-		add	ip, sp, #S_OFF
-		ldmleib	ip, {r0 - r3, SYSCALL_REGS}	@ get our args
-		stmleia	sp, {SYSCALL_REGS}	@ Put our arg on the stack
+		stmleia	sp, {r5, r6}		@ shuffle args
+		movle	r0, r1
+		movle	r1, r2
+		movle	r2, r3
+		movle	r3, r4
 		ldrle	pc, [tbl, scno, lsl #2]
-		mov	r0, #-ENOSYS
-		RETINSTR(mov,pc,lr)
+		b	sys_ni_syscall
 
 sys_fork_wrapper:
 		add	r0, sp, #S_OFF
@@ -198,6 +189,23 @@
 sys_sigaltstack_wrapper:
 		ldr	r2, [sp, #S_OFF + S_SP]
 		b	do_sigaltstack
+
+/*
+ * Note: off_4k is always units of 4K.  If we can't do the requested
+ * offset, we return EINVAL.
+ */
+sys_mmap2:
+#if PAGE_SHIFT > 12
+		tst	r5, #PGOFF_MASK
+		moveq	r5, r5, lsr #PGOFF_SHIFT
+		streq	r5, [sp, #4]
+		beq	do_mmap2
+		mov	r0, #-EINVAL
+		mov	pc, lr
+#else
+		str	r5, [sp, #4]
+		b	do_mmap2
+#endif
 
 		.data
 
diff -udpNr rmk/linux/arch/arm/kernel/sys_arm.c linux-000227/arch/arm/kernel/sys_arm.c
--- rmk/linux/arch/arm/kernel/sys_arm.c	Mon Feb  7 21:23:42 2000
+++ linux-000227/arch/arm/kernel/sys_arm.c	Mon Feb  7 22:02:55 2000
@@ -50,7 +50,7 @@ asmlinkage int sys_pipe(unsigned long * 
 }
 
 /* common code for old and new mmaps */
-static inline long do_mmap2(
+long int do_mmap2(
 	unsigned long addr, unsigned long len,
 	unsigned long prot, unsigned long flags,
 	unsigned long fd, unsigned long pgoff)
@@ -77,27 +77,6 @@ static inline long do_mmap2(
 		fput(file);
 out:
 	return error;
-}
-
-#define PGOFF_SHIFT (PAGE_SHIFT - 12)
-#define PGOFF_MASK  (~((1 << PGOFF_SHIFT) - 1))
-
-/*
- * Note: off_4k is always units of 4K.  If we can't do the requested
- * offset, we return EINVAL.
- */
-asmlinkage long
-sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
-	  unsigned long flags, unsigned long fd, unsigned long off_4k)
-{
-	unsigned long pgoff;
-
-	if (off_4k & ~PGOFF_MASK)
-		return -EINVAL;
-
-	pgoff = off_4k >> PGOFF_SHIFT;
-
-	return do_mmap2(addr, len, prot, flags, fd, pgoff);
 }
 
 struct mmap_arg_struct {

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