public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC] 2.5.8 sort kernel tables
@ 2002-04-18  9:46 Keith Owens
  2002-04-18 10:21 ` Matthias Andree
                   ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Keith Owens @ 2002-04-18  9:46 UTC (permalink / raw)
  To: linux-kernel

The use of __init and __exit sections breaks the assumption that tables
such as __ex_table are sorted, it has already broken the dbe table in
mips on 2.5.  This patch against 2.5.8 adds a generic sort routine and
sorts the i386 exception table.

This sorting needs to be extended to several other tables, to all
architectures, to modutils (insmod loads some of these tables for
modules) and back ported to 2.4.  Before I spend the rest of the time,
any objections?

ndex: 8.1/init/main.c
--- 8.1/init/main.c Mon, 15 Apr 2002 13:28:23 +1000 kaos (linux-2.5/w/d/29_main.c 1.16 444)
+++ 8.1(w)/init/main.c Thu, 18 Apr 2002 19:36:40 +1000 kaos (linux-2.5/w/d/29_main.c 1.16 444)
@@ -257,6 +257,56 @@ static void __init parse_options(char *l
 	envp_init[envs+1] = NULL;
 }
 
+/* Quick and dirty bubble sort to ensure that certain kernel tables really are
+ * sorted.  Various kernel tables, in particular the exception entries, are
+ * assumed to be in ascending order.  These tables are built by the linker from
+ * sections in each object.  The linker is not a problem, it appends entries to
+ * the tables as each object is added to vmlinux.  However the use of __init and
+ * __exit in objects can break the ordering, within each object the entries are
+ * in order, the linker appends them in order but the entries are not in order
+ * across objects.
+ *
+ * Do not assume that the table from the linker is correct, sort it at boot
+ * time.  Since 90%+ of the entries will be sorted, a bubble sort is good
+ * enough, it only runs once per table per boot.  The sort only does binary
+ * keys and only sorts in ascending order.
+ */
+
+void __init sort_table(void *table, size_t entry_size, size_t entries, size_t key_size, size_t key_offset)
+{
+	char *a, *b;
+	int i, j, changed = 1;
+	char save[entry_size];
+	a = (char *)table;
+	if (key_size != 4 && key_size != 8) {
+		printk(KERN_ERR "sort_table key_size %d is incorrect\n", key_size);
+		return;
+	}
+	for (i = 0; i < entries && changed; a += entry_size, ++i) {
+		changed = 0;
+		b = a + entry_size;
+		for (j = i + 1; j < entries; b += entry_size, ++j) {
+			if (key_size == 4) {
+				if (*((__u32 *)(b+key_offset-entry_size)) >
+				    *((__u32 *)(b+key_offset))) {
+					memcpy(save, b, entry_size);
+					memcpy(b, b-entry_size, entry_size);
+					memcpy(b-entry_size, save, entry_size);
+					changed = 1;
+				}
+			}
+			else {
+				if (*((__u64 *)(b+key_offset-entry_size)) >
+				    *((__u64 *)(b+key_offset))) {
+					memcpy(save, b, entry_size);
+					memcpy(b, b-entry_size, entry_size);
+					memcpy(b-entry_size, save, entry_size);
+					changed = 1;
+				}
+			}
+		}
+	}
+}
 
 extern void setup_arch(char **);
 extern void cpu_idle(void);
@@ -343,6 +393,7 @@ asmlinkage void __init start_kernel(void
  */
 	lock_kernel();
 	printk(linux_banner);
+	sort_arch_tables();
 	setup_arch(&command_line);
 	setup_per_cpu_areas();
 	printk("Kernel command line: %s\n", saved_command_line);
Index: 8.1/arch/i386/mm/extable.c
--- 8.1/arch/i386/mm/extable.c Sat, 24 Nov 2001 05:28:08 +1100 kaos (linux-2.5/b/b/41_extable.c 1.1 444)
+++ 8.1(w)/arch/i386/mm/extable.c Thu, 18 Apr 2002 19:37:50 +1000 kaos (linux-2.5/b/b/41_extable.c 1.1 444)
@@ -31,6 +31,14 @@ search_one_table(const struct exception_
         return 0;
 }
 
+void __init sort_arch_tables(void)
+{
+	sort_table((void *) __start___ex_table, sizeof(*__start___ex_table),
+			__stop___ex_table - __start___ex_table,
+			sizeof(__start___ex_table->insn),
+			offsetof(typeof(*__start___ex_table), insn));
+}
+
 extern spinlock_t modlist_lock;
 
 unsigned long
Index: 8.1/include/linux/kernel.h
--- 8.1/include/linux/kernel.h Sat, 09 Feb 2002 15:37:49 +1100 kaos (linux-2.5/v/d/17_kernel.h 1.4 444)
+++ 8.1(w)/include/linux/kernel.h Thu, 18 Apr 2002 18:38:26 +1000 kaos (linux-2.5/v/d/17_kernel.h 1.4 444)
@@ -95,6 +95,9 @@ extern const char *print_tainted(void);
 #define TAINT_FORCED_MODULE		(1<<1)
 #define TAINT_UNSAFE_SMP		(1<<2)
 
+extern void sort_arch_tables(void);
+extern void sort_table(void *table, size_t entry_size, size_t entries, size_t key_size, size_t key_offset);
+
 #if DEBUG
 #define pr_debug(fmt,arg...) \
 	printk(KERN_DEBUG fmt,##arg)


^ permalink raw reply	[flat|nested] 24+ messages in thread
[parent not found: <1589.1019123186@ocs3.intra.ocs.com.au.suse.lists.linux.kernel>]
* RE: [RFC] 2.5.8 sort kernel tables
@ 2002-04-19 11:38 Randal, Phil
  2002-04-20  5:19 ` Keith Owens
  0 siblings, 1 reply; 24+ messages in thread
From: Randal, Phil @ 2002-04-19 11:38 UTC (permalink / raw)
  To: 'Matt', linux-kernel

This variation on Quicksort seems superior...  Must look at the libc
sources someday to see how it does it...

http://www.neubert.net/Flapaper/9802n.htm

For small arrays, Insertion Sort has the least overhead.

Cheers,

Phil

P.S. A google for quickersort yields loads of interesting references.

---------------------------------------------
Phil Randal
Network Engineer
Herefordshire Council
Hereford, UK 

> -----Original Message-----
> From: Matt [mailto:matt@progsoc.uts.edu.au]
> Sent: 19 April 2002 06:00
> To: linux-kernel@vger.kernel.org
> Subject: Re: [RFC] 2.5.8 sort kernel tables
> 
> 
> On Thu, Apr 18, 2002 at 03:20:17PM -0500, Oliver Xymoron wrote:
> > On Thu, 18 Apr 2002, William Lee Irwin III wrote:
> 
> >> On Thu, Apr 18, 2002 at 07:46:26PM +1000, Keith Owens wrote:
> 
> >>> The use of __init and __exit sections breaks the assumption that
> >>> tables such as __ex_table are sorted, it has already broken the
> >>> dbe table in mips on 2.5.  This patch against 2.5.8 adds a generic
> >>> sort routine and sorts the i386 exception table.  This sorting
> >>> needs to be extended to several other tables, to all
> >>> architectures, to modutils (insmod loads some of these tables for
> >>> modules) and back ported to 2.4.  Before I spend the rest of the
> >>> time, any objections?
> 
> >> It doesn't have to be an O(n lg(n)) method but could you use
> >> something besides bubblesort? Insertion sort, selection sort,
> >> etc. are just as easy and they don't have the horrific stigma of
> >> being "the worst sorting algorithm ever" etc.
> 
> > Combsort is a trivial modification of bubblesort that's O(n log(n)).
> 
> >  http://cs.clackamas.cc.or.us/molatore/cs260Spr01/combsort.htm
> 
> > Though we should probably just stick a simple qsort in the library
> > somewhere.
> 
> but isn't qsort's worst case behaviour for an already sorted list? i
> cant remember how bad it is but i thought it was like O(n^2) for worst
> case, ie just as bad as bubble sort..
> 
> 	matt
> -
> To unsubscribe from this list: send the line "unsubscribe 
> linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2002-04-20  9:41 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-04-18  9:46 [RFC] 2.5.8 sort kernel tables Keith Owens
2002-04-18 10:21 ` Matthias Andree
2002-04-18 10:32   ` Keith Owens
2002-04-18 10:52   ` Alan Cox
2002-04-18 13:02 ` Paul Mackerras
2002-04-18 15:38   ` Keith Owens
2002-04-18 15:52     ` Russell King
2002-04-18 16:09       ` Keith Owens
2002-04-18 13:59 ` William Lee Irwin III
2002-04-18 18:16   ` Kai Henningsen
2002-04-18 18:24     ` William Lee Irwin III
2002-04-19 11:46     ` David Weinehall
2002-04-18 20:20   ` Oliver Xymoron
2002-04-19  4:59     ` Matt
2002-04-19 13:45     ` Jamie Lokier
2002-04-19 13:46     ` Jamie Lokier
2002-04-19 14:25       ` Oliver Xymoron
2002-04-19 15:16         ` Tobias Wollgam
     [not found] <1589.1019123186@ocs3.intra.ocs.com.au.suse.lists.linux.kernel>
     [not found] ` <15550.50131.489249.256007@nanango.paulus.ozlabs.org.suse.lists.linux.kernel>
2002-04-18 17:51   ` Andi Kleen
2002-04-18 23:17     ` Keith Owens
  -- strict thread matches above, loose matches on Subject: below --
2002-04-19 11:38 Randal, Phil
2002-04-20  5:19 ` Keith Owens
2002-04-20  8:50   ` Alan Cox
2002-04-20  9:40     ` Keith Owens

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox