A couple of performance patches

Robert L Krawitz (rlk@tiac.net)
Tue, 20 Feb 1996 10:28:40 -0500


The first one of these speeds up exec somewhat, particularly if there
are a lot of command line arguments or environment variables set. The
second one simply speeds up copying page directory descriptors.

Index: linux-1.3/fs/exec.c
diff -u linux-1.3/fs/exec.c:1.1.1.19 linux-1.3/fs/exec.c:1.14
--- linux-1.3/fs/exec.c:1.1.1.19 Sat Feb 10 10:16:55 1996
+++ linux-1.3/fs/exec.c Sat Feb 10 10:32:38 1996
@@ -290,7 +290,7 @@
unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
unsigned long p, int from_kmem)
{
- char *tmp, *pag = NULL;
+ char *tmp, *tmp1, *pag = NULL;
int len, offset = 0;
unsigned long old_fs, new_fs;

@@ -303,14 +303,12 @@
while (argc-- > 0) {
if (from_kmem == 1)
set_fs(new_fs);
- if (!(tmp = get_user(argv+argc)))
+ if (!(tmp1 = tmp = get_user(argv+argc)))
panic("VFS: argc is wrong");
if (from_kmem == 1)
set_fs(old_fs);
- len=0; /* remember zero-padding */
- do {
- len++;
- } while (get_user(tmp++));
+ while (get_user(tmp++));
+ len = tmp - tmp1;
if (p < len) { /* this shouldn't happen - 128kB */
set_fs(old_fs);
return 0;
@@ -329,7 +327,16 @@
set_fs(new_fs);

}
- *(pag + offset) = get_user(tmp);
+ if (len == 0 || offset == 0)
+ *(pag + offset) = get_user(tmp);
+ else {
+ int bytes_to_copy = (len > offset) ? offset : len;
+ tmp -= bytes_to_copy;
+ p -= bytes_to_copy;
+ offset -= bytes_to_copy;
+ len -= bytes_to_copy;
+ memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1);
+ }
}
}
if (from_kmem==2)
Index: linux-1.3/mm/memory.c
diff -u linux-1.3/mm/memory.c:1.1.1.19 linux-1.3/mm/memory.c:1.18
--- linux-1.3/mm/memory.c:1.1.1.19 Sat Jan 13 10:29:15 1996
+++ linux-1.3/mm/memory.c Sat Jan 13 14:29:49 1996
@@ -48,6 +48,7 @@
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/pgtable.h>
+#include <asm/string.h>

unsigned long high_memory = 0;

@@ -182,8 +183,12 @@
if (!(new_pg = pgd_alloc()))
return -ENOMEM;
page_dir = pgd_offset(&init_mm, 0);
+ memcpy(&(new_pg[USER_PTRS_PER_PGD]), &(page_dir[USER_PTRS_PER_PGD]),
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof (pgd_t));
+#if 0
for (i = USER_PTRS_PER_PGD ; i < PTRS_PER_PGD ; i++)
new_pg[i] = page_dir[i];
+#endif
invalidate_mm(tsk->mm);
SET_PAGE_DIR(tsk, new_pg);
tsk->mm->pgd = new_pg;