From: Mike Ditto <mditto@google.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Stefan Assmann <sassmann@kpanic.de>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
tony.luck@intel.com, andi@firstfloor.org, mingo@elte.hu,
hpa@zytor.com, rick@vanrein.org, rdunlap@xenotime.net,
Nancy Yuen <yuenn@google.com>
Subject: [PATCH] x86: e820: Eliminate bubble sort from sanitize_e820_map
Date: Wed, 22 Jun 2011 12:46:04 -0700 [thread overview]
Message-ID: <4E02467C.6090106@google.com> (raw)
In-Reply-To: <20110622110034.89ee399c.akpm@linux-foundation.org>
Replace the bubble sort in sanitize_e820_map() with a call to the generic
kernel sort function to avoid pathological performance with large maps.
On large (thousands of entries) E820 maps, the previous code took minutes
to run; with this change it's now milliseconds.
Signed-off-by: Mike Ditto <mditto@google.com>
---
This is a small independent part of Google's BadRAM changes mentioned in
another thread.
arch/x86/kernel/e820.c | 59 +++++++++++++++++++----------------------------
1 files changed, 24 insertions(+), 35 deletions(-)
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 3e2ef84..e2e212a 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -18,6 +18,7 @@
#include <linux/acpi.h>
#include <linux/firmware-map.h>
#include <linux/memblock.h>
+#include <linux/sort.h>
#include <asm/e820.h>
#include <asm/proto.h>
@@ -226,22 +227,38 @@ void __init e820_print_map(char *who)
* ____________________33__
* ______________________4_
*/
+struct change_member {
+ struct e820entry *pbios; /* pointer to original bios entry */
+ unsigned long long addr; /* address for this change point */
+};
+
+static int __init cpcompare(const void *a, const void *b)
+{
+ struct change_member * const *app = a, * const *bpp = b;
+ const struct change_member *ap = *app, *bp = *bpp;
+
+ /*
+ * Inputs are pointers to two elements of change_point[]. If their
+ * addresses are unequal, their difference dominates. If the addresses
+ * are equal, then consider one that represents the end of its region
+ * to be greater than one that does not.
+ */
+ if (ap->addr != bp->addr)
+ return ap->addr > bp->addr ? 1 : -1;
+
+ return (ap->addr != ap->pbios->addr) - (bp->addr != bp->pbios->addr);
+}
int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
u32 *pnr_map)
{
- struct change_member {
- struct e820entry *pbios; /* pointer to original bios entry */
- unsigned long long addr; /* address for this change point */
- };
static struct change_member change_point_list[2*E820_X_MAX] __initdata;
static struct change_member *change_point[2*E820_X_MAX] __initdata;
static struct e820entry *overlap_list[E820_X_MAX] __initdata;
static struct e820entry new_bios[E820_X_MAX] __initdata;
- struct change_member *change_tmp;
unsigned long current_type, last_type;
unsigned long long last_addr;
- int chgidx, still_changing;
+ int chgidx;
int overlap_entries;
int new_bios_entry;
int old_nr, new_nr, chg_nr;
@@ -278,35 +295,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
chg_nr = chgidx;
/* sort change-point list by memory addresses (low -> high) */
- still_changing = 1;
- while (still_changing) {
- still_changing = 0;
- for (i = 1; i < chg_nr; i++) {
- unsigned long long curaddr, lastaddr;
- unsigned long long curpbaddr, lastpbaddr;
-
- curaddr = change_point[i]->addr;
- lastaddr = change_point[i - 1]->addr;
- curpbaddr = change_point[i]->pbios->addr;
- lastpbaddr = change_point[i - 1]->pbios->addr;
-
- /*
- * swap entries, when:
- *
- * curaddr > lastaddr or
- * curaddr == lastaddr and curaddr == curpbaddr and
- * lastaddr != lastpbaddr
- */
- if (curaddr < lastaddr ||
- (curaddr == lastaddr && curaddr == curpbaddr &&
- lastaddr != lastpbaddr)) {
- change_tmp = change_point[i];
- change_point[i] = change_point[i-1];
- change_point[i-1] = change_tmp;
- still_changing = 1;
- }
- }
- }
+ sort(change_point, chg_nr, sizeof *change_point, cpcompare, 0);
/* create a new bios memory map, removing overlaps */
overlap_entries = 0; /* number of entries in the overlap table */
--
1.7.3.1
WARNING: multiple messages have this Message-ID (diff)
From: Mike Ditto <mditto@google.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Stefan Assmann <sassmann@kpanic.de>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
tony.luck@intel.com, andi@firstfloor.org, mingo@elte.hu,
hpa@zytor.com, rick@vanrein.org, rdunlap@xenotime.net,
Nancy Yuen <yuenn@google.com>
Subject: [PATCH] x86: e820: Eliminate bubble sort from sanitize_e820_map
Date: Wed, 22 Jun 2011 12:46:04 -0700 [thread overview]
Message-ID: <4E02467C.6090106@google.com> (raw)
In-Reply-To: <20110622110034.89ee399c.akpm@linux-foundation.org>
Replace the bubble sort in sanitize_e820_map() with a call to the generic
kernel sort function to avoid pathological performance with large maps.
On large (thousands of entries) E820 maps, the previous code took minutes
to run; with this change it's now milliseconds.
Signed-off-by: Mike Ditto <mditto@google.com>
---
This is a small independent part of Google's BadRAM changes mentioned in
another thread.
arch/x86/kernel/e820.c | 59 +++++++++++++++++++----------------------------
1 files changed, 24 insertions(+), 35 deletions(-)
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 3e2ef84..e2e212a 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -18,6 +18,7 @@
#include <linux/acpi.h>
#include <linux/firmware-map.h>
#include <linux/memblock.h>
+#include <linux/sort.h>
#include <asm/e820.h>
#include <asm/proto.h>
@@ -226,22 +227,38 @@ void __init e820_print_map(char *who)
* ____________________33__
* ______________________4_
*/
+struct change_member {
+ struct e820entry *pbios; /* pointer to original bios entry */
+ unsigned long long addr; /* address for this change point */
+};
+
+static int __init cpcompare(const void *a, const void *b)
+{
+ struct change_member * const *app = a, * const *bpp = b;
+ const struct change_member *ap = *app, *bp = *bpp;
+
+ /*
+ * Inputs are pointers to two elements of change_point[]. If their
+ * addresses are unequal, their difference dominates. If the addresses
+ * are equal, then consider one that represents the end of its region
+ * to be greater than one that does not.
+ */
+ if (ap->addr != bp->addr)
+ return ap->addr > bp->addr ? 1 : -1;
+
+ return (ap->addr != ap->pbios->addr) - (bp->addr != bp->pbios->addr);
+}
int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
u32 *pnr_map)
{
- struct change_member {
- struct e820entry *pbios; /* pointer to original bios entry */
- unsigned long long addr; /* address for this change point */
- };
static struct change_member change_point_list[2*E820_X_MAX] __initdata;
static struct change_member *change_point[2*E820_X_MAX] __initdata;
static struct e820entry *overlap_list[E820_X_MAX] __initdata;
static struct e820entry new_bios[E820_X_MAX] __initdata;
- struct change_member *change_tmp;
unsigned long current_type, last_type;
unsigned long long last_addr;
- int chgidx, still_changing;
+ int chgidx;
int overlap_entries;
int new_bios_entry;
int old_nr, new_nr, chg_nr;
@@ -278,35 +295,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
chg_nr = chgidx;
/* sort change-point list by memory addresses (low -> high) */
- still_changing = 1;
- while (still_changing) {
- still_changing = 0;
- for (i = 1; i < chg_nr; i++) {
- unsigned long long curaddr, lastaddr;
- unsigned long long curpbaddr, lastpbaddr;
-
- curaddr = change_point[i]->addr;
- lastaddr = change_point[i - 1]->addr;
- curpbaddr = change_point[i]->pbios->addr;
- lastpbaddr = change_point[i - 1]->pbios->addr;
-
- /*
- * swap entries, when:
- *
- * curaddr > lastaddr or
- * curaddr == lastaddr and curaddr == curpbaddr and
- * lastaddr != lastpbaddr
- */
- if (curaddr < lastaddr ||
- (curaddr == lastaddr && curaddr == curpbaddr &&
- lastaddr != lastpbaddr)) {
- change_tmp = change_point[i];
- change_point[i] = change_point[i-1];
- change_point[i-1] = change_tmp;
- still_changing = 1;
- }
- }
- }
+ sort(change_point, chg_nr, sizeof *change_point, cpcompare, 0);
/* create a new bios memory map, removing overlaps */
overlap_entries = 0; /* number of entries in the overlap table */
--
1.7.3.1
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2011-06-22 19:46 UTC|newest]
Thread overview: 86+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-22 11:18 [PATCH v2 0/3] support for broken memory modules (BadRAM) Stefan Assmann
2011-06-22 11:18 ` Stefan Assmann
2011-06-22 11:18 ` [PATCH v2 1/3] Add string parsing function get_next_ulong Stefan Assmann
2011-06-22 11:18 ` Stefan Assmann
2011-06-22 11:18 ` [PATCH v2 2/3] support for broken memory modules (BadRAM) Stefan Assmann
2011-06-22 11:18 ` Stefan Assmann
2011-06-22 11:18 ` [PATCH v2 3/3] Add documentation and credits for BadRAM Stefan Assmann
2011-06-22 11:18 ` Stefan Assmann
2011-06-22 18:00 ` [PATCH v2 0/3] support for broken memory modules (BadRAM) Andrew Morton
2011-06-22 18:00 ` Andrew Morton
2011-06-22 18:06 ` Josh Boyer
2011-06-22 18:06 ` Josh Boyer
2011-06-22 18:09 ` Randy Dunlap
2011-06-22 18:09 ` Randy Dunlap
2011-06-22 18:11 ` Nancy Yuen
2011-06-22 18:11 ` Nancy Yuen
2011-06-22 18:13 ` H. Peter Anvin
2011-06-22 18:13 ` H. Peter Anvin
2011-06-22 19:01 ` Nancy Yuen
2011-06-22 19:01 ` Nancy Yuen
2011-06-22 19:06 ` H. Peter Anvin
2011-06-22 19:06 ` H. Peter Anvin
2011-06-22 18:24 ` Andi Kleen
2011-06-22 18:24 ` Andi Kleen
2011-06-22 18:38 ` Andrew Morton
2011-06-22 18:38 ` Andrew Morton
2011-06-22 18:56 ` Andi Kleen
2011-06-22 18:56 ` Andi Kleen
2011-06-22 19:05 ` H. Peter Anvin
2011-06-22 19:05 ` H. Peter Anvin
2011-06-22 19:15 ` Andi Kleen
2011-06-22 19:15 ` Andi Kleen
2011-06-22 20:25 ` H. Peter Anvin
2011-06-22 20:25 ` H. Peter Anvin
2011-06-22 20:28 ` Andi Kleen
2011-06-22 20:28 ` Andi Kleen
2011-06-22 19:46 ` Mike Ditto [this message]
2011-06-22 19:46 ` [PATCH] x86: e820: Eliminate bubble sort from sanitize_e820_map Mike Ditto
2011-06-22 20:18 ` [PATCH v2 0/3] support for broken memory modules (BadRAM) Stefan Assmann
2011-06-22 20:18 ` Stefan Assmann
2011-06-23 10:10 ` Rick van Rein
2011-06-23 10:10 ` Rick van Rein
2011-06-22 18:15 ` H. Peter Anvin
2011-06-22 18:15 ` H. Peter Anvin
2011-06-22 20:30 ` Stefan Assmann
2011-06-22 20:30 ` Stefan Assmann
2011-06-22 20:33 ` H. Peter Anvin
2011-06-22 20:33 ` H. Peter Anvin
2011-06-23 10:33 ` Rick van Rein
2011-06-23 10:33 ` Rick van Rein
2011-06-23 10:49 ` Rick van Rein
2011-06-23 10:49 ` Rick van Rein
2011-06-23 13:39 ` Matthew Garrett
2011-06-23 13:39 ` Matthew Garrett
2011-06-23 14:08 ` Stefan Assmann
2011-06-23 14:08 ` Stefan Assmann
2011-06-23 14:12 ` Matthew Garrett
2011-06-23 14:12 ` Matthew Garrett
2011-06-23 15:37 ` Stefan Assmann
2011-06-23 15:37 ` Stefan Assmann
2011-06-23 16:30 ` H. Peter Anvin
2011-06-23 16:30 ` H. Peter Anvin
2011-06-24 0:59 ` Andi Kleen
2011-06-24 0:59 ` Andi Kleen
2011-06-23 17:00 ` Andi Kleen
2011-06-23 17:00 ` Andi Kleen
2011-06-23 17:12 ` Luck, Tony
2011-06-23 17:12 ` Luck, Tony
2011-06-24 1:03 ` Craig Bergstrom
2011-06-24 1:08 ` Andi Kleen
2011-06-24 1:08 ` Andi Kleen
2011-06-24 1:22 ` Craig Bergstrom
2011-06-24 1:22 ` Craig Bergstrom
2011-06-24 8:05 ` Rick van Rein
2011-06-24 8:05 ` Rick van Rein
2011-06-24 14:34 ` Craig Bergstrom
2011-06-24 14:35 ` Craig Bergstrom
2011-06-24 16:16 ` H. Peter Anvin
2011-06-24 16:16 ` H. Peter Anvin
2011-06-24 16:40 ` Luck, Tony
2011-06-24 16:40 ` Luck, Tony
2011-06-24 16:56 ` Rick van Rein
2011-06-24 16:56 ` Rick van Rein
2011-06-24 17:14 ` H. Peter Anvin
2011-06-24 17:14 ` H. Peter Anvin
2011-06-24 1:09 ` Craig Bergstrom
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=4E02467C.6090106@google.com \
--to=mditto@google.com \
--cc=akpm@linux-foundation.org \
--cc=andi@firstfloor.org \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mingo@elte.hu \
--cc=rdunlap@xenotime.net \
--cc=rick@vanrein.org \
--cc=sassmann@kpanic.de \
--cc=tony.luck@intel.com \
--cc=yuenn@google.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.