All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yinghai Lu <yhlu.kernel.send@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>,
	Ingo Molnar <mingo@elte.hu>, "H. Peter Anvin" <hpa@zytor.com>,
	Thomas Gleixner <tglx@linutronix.de>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Gabriel C <nix.or.die@googlemail.com>,
	Mika Fischer <mika.fischer@zoopnet.de>
Subject: [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v3
Date: Mon, 28 Apr 2008 12:44:56 -0700	[thread overview]
Message-ID: <200804281244.56938.yhlu.kernel@gmail.com> (raw)
In-Reply-To: <200804280206.52641.yhlu.kernel@gmail.com>


some BIOS like to use continus MTRR layout, and some X driver can not add
WB entries for graphical cards when 4g or more RAM installed.

the patch will change MTRR to discrete.

mtrr_chunk_size= could be used to have smaller continuous block to hold holes.
default is 256m, could be set according to size of graphics card memory.

v2: fix -1 for UC checking
v3: default to disable, and need use enable_mtrr_cleanup to enable this feature
    skip the var state change warning.
    remove next_basek in range_to_mtrr()

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>

Index: linux-2.6/arch/x86/kernel/cpu/mtrr/generic.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/mtrr/generic.c
+++ linux-2.6/arch/x86/kernel/cpu/mtrr/generic.c
@@ -158,6 +158,20 @@ get_mtrr_var_range(unsigned int index, s
 	rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
 }
 
+/*  fill the MSR pair relating to a var range  */
+void fill_mtrr_var_range(unsigned int index,
+		u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi)
+{
+	struct mtrr_var_range *vr;
+
+	vr = mtrr_state.var_ranges;
+
+	vr[index].base_lo = base_lo;
+	vr[index].base_hi = base_hi;
+	vr[index].mask_lo = mask_lo;
+	vr[index].mask_hi = mask_hi;
+}
+
 static void
 get_fixed_ranges(mtrr_type * frs)
 {
Index: linux-2.6/arch/x86/kernel/cpu/mtrr/main.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/mtrr/main.c
+++ linux-2.6/arch/x86/kernel/cpu/mtrr/main.c
@@ -37,6 +37,7 @@
 #include <linux/smp.h>
 #include <linux/cpu.h>
 #include <linux/mutex.h>
+#include <linux/sort.h>
 
 #include <asm/e820.h>
 #include <asm/mtrr.h>
@@ -609,6 +610,345 @@ static struct sysdev_driver mtrr_sysdev_
 	.resume		= mtrr_restore,
 };
 
+static int __initdata enable_mtrr_cleanup;
+
+static int __init enable_mtrr_cleanup_setup(char *str)
+{
+	enable_mtrr_cleanup = 1;
+	return 0;
+}
+early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
+
+#define RANGE_NUM 256
+
+struct res_range {
+	size_t start;
+	size_t end;
+};
+
+static void __init subtract_range(struct res_range *range, size_t start,
+				size_t end)
+{
+	int i;
+	int j;
+
+	for (j = 0; j < RANGE_NUM; j++) {
+		if (!range[j].end)
+			continue;
+
+		if (start <= range[j].start && end >= range[j].end) {
+			range[j].start = 0;
+			range[j].end = 0;
+			continue;
+		}
+
+		if (start <= range[j].start && end < range[j].end && range[j].start < end + 1) {
+			range[j].start = end + 1;
+			continue;
+		}
+
+
+		if (start > range[j].start && end >= range[j].end && range[j].end > start - 1) {
+			range[j].end = start - 1;
+			continue;
+		}
+
+		if (start > range[j].start && end < range[j].end) {
+			/* find the new spare */
+			for (i = 0; i < RANGE_NUM; i++) {
+				if (range[i].end == 0)
+					break;
+			}
+			if (i < RANGE_NUM) {
+				range[i].end = range[j].end;
+				range[i].start = end + 1;
+			} else {
+				printk(KERN_ERR "run of slot in ranges\n");
+			}
+			range[j].end = start - 1;
+			continue;
+		}
+	}
+}
+
+static int __cpuinit cmp_range(const void *x1, const void *x2)
+{
+	const struct res_range *r1 = x1;
+	const struct res_range *r2 = x2;
+	s64 start1, start2;
+
+	start1 = r1->start;
+	start2 = r2->start;
+
+	return start1 - start2;
+}
+
+struct var_mtrr_state {
+	unsigned long range_startk, range_sizek;
+	unsigned long chunk_sizek;
+	unsigned int reg;
+	unsigned address_bits;
+};
+
+static void __init set_var_mtrr(
+	unsigned int reg, unsigned long basek, unsigned long sizek,
+	unsigned char type, unsigned address_bits)
+{
+	u32 base_lo, base_hi, mask_lo, mask_hi;
+	unsigned address_mask_high;
+
+	if (!sizek) {
+		fill_mtrr_var_range(reg, 0, 0, 0, 0);
+		return;
+	}
+
+	address_mask_high = ((1u << (address_bits - 32u)) - 1u);
+
+	base_hi = basek >> 22;
+	base_lo  = basek << 10;
+
+	if (sizek < 4*1024*1024) {
+		mask_hi = address_mask_high;
+		mask_lo = ~((sizek << 10) - 1);
+	} else {
+		mask_hi = address_mask_high & (~((sizek >> 22) - 1));
+		mask_lo = 0;
+	}
+
+	base_lo |= type;
+	mask_lo |= 0x800;
+	fill_mtrr_var_range(reg, base_lo, base_hi, mask_lo, mask_hi);
+}
+
+static unsigned int __init range_to_mtrr(unsigned int reg,
+	unsigned long range_startk, unsigned long range_sizek,
+	unsigned char type, unsigned address_bits)
+{
+	if (!range_sizek || (reg >= num_var_ranges))
+		return reg;
+
+	while (range_sizek) {
+		unsigned long max_align, align;
+		unsigned long sizek;
+		/* Compute the maximum size I can make a range */
+		if (range_startk)
+			max_align = ffs(range_startk) - 1;
+		else
+			max_align = 32;
+		align = fls(range_sizek) - 1;
+		if (align > max_align)
+			align = max_align;
+
+		sizek = 1 << align;
+		printk(KERN_INFO "Setting variable MTRR %d, base: %ldMB, range: %ldMB, type %s\n",
+			reg, range_startk >> 10, sizek >> 10,
+			(type == MTRR_TYPE_UNCACHABLE)?"UC":
+			    ((type == MTRR_TYPE_WRBACK)?"WB":"Other")
+			);
+		set_var_mtrr(reg++, range_startk, sizek, type, address_bits);
+		range_startk += sizek;
+		range_sizek -= sizek;
+		if (reg >= num_var_ranges)
+			break;
+	}
+	return reg;
+}
+
+static void __init range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek)
+{
+	unsigned long hole_basek, hole_sizek;
+	unsigned long range0_basek, range0_sizek;
+	unsigned long range_basek, range_sizek;
+	unsigned long chunk_sizek;
+
+	hole_basek = 0;
+	hole_sizek = 0;
+	chunk_sizek = state->chunk_sizek;
+	range0_basek = state->range_startk;
+
+	/* try to append some small hole */
+	range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
+	if ((range0_sizek == state->range_sizek) ||
+		((range0_basek + range0_sizek > basek) && basek)) {
+			printk(KERN_INFO "rangeX: %016lx - %016lx\n", range0_basek<<10, (range0_basek + range0_sizek)<<10);
+			state->reg = range_to_mtrr(state->reg, range0_basek,
+				range0_sizek, MTRR_TYPE_WRBACK, state->address_bits);
+		return;
+	}
+
+	range0_sizek -= chunk_sizek;
+	range_basek = range0_basek + range0_sizek;
+	printk(KERN_INFO "range0: %016lx - %016lx\n", range0_basek<<10, (range0_basek + range0_sizek)<<10);
+	state->reg = range_to_mtrr(state->reg, range0_basek,
+			range0_sizek, MTRR_TYPE_WRBACK, state->address_bits);
+
+	range_sizek = chunk_sizek;
+	if (range_sizek - (state->range_sizek - range0_sizek) < (chunk_sizek >> 1))
+		hole_sizek = range_sizek - (state->range_sizek - range0_sizek);
+	else
+		range_sizek = state->range_sizek - range0_sizek;
+
+	printk(KERN_INFO "range: %016lx - %016lx\n", range_basek<<10, (range_basek + range_sizek)<<10);
+	state->reg = range_to_mtrr(state->reg, range_basek,
+			range_sizek, MTRR_TYPE_WRBACK, state->address_bits);
+	if (hole_sizek) {
+		printk(KERN_INFO "hole: %016lx - %016lx\n", hole_basek<<10, (hole_basek + hole_sizek)<<10);
+		state->reg = range_to_mtrr(state->reg, hole_basek,
+				hole_sizek, MTRR_TYPE_UNCACHABLE, state->address_bits);
+	}
+}
+
+static void __init set_var_mtrr_range(struct var_mtrr_state *state, size_t base_pfn, size_t size_pfn)
+{
+	unsigned long basek, sizek;
+
+	if (state->reg >= num_var_ranges)
+		return;
+
+	basek = base_pfn << (PAGE_SHIFT - 10);
+	sizek = size_pfn << (PAGE_SHIFT - 10);
+
+	/* See if I can merge with the last range */
+	if ((basek <= 1024) || (state->range_startk + state->range_sizek == basek)) {
+		unsigned long endk = basek + sizek;
+		state->range_sizek = endk - state->range_startk;
+		return;
+	}
+	/* Write the range mtrrs */
+	if (state->range_sizek != 0) {
+		range_to_mtrr_with_hole(state, basek);
+
+		state->range_startk = 0;
+		state->range_sizek = 0;
+	}
+	/* Allocate an msr */
+	state->range_startk = basek;
+	state->range_sizek  = sizek;
+}
+
+static u64 mtrr_chunk_size __initdata = (256ULL<<20);
+
+static int __init parse_mtrr_chunk_size_opt(char *p)
+{
+	if (!p)
+		return -EINVAL;
+	mtrr_chunk_size = memparse(p, &p);
+	return 0;
+}
+early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt);
+
+static void __init x86_setup_var_mtrrs(struct res_range *range, int nr_range, unsigned address_bits)
+{
+	struct var_mtrr_state var_state;
+	int i;
+
+	var_state.range_startk = 0;
+	var_state.range_sizek = 0;
+	var_state.reg = 0;
+	var_state.address_bits = address_bits;
+	var_state.chunk_sizek = mtrr_chunk_size >> 10;
+
+	/* Write the range etc */
+	for (i = 0; i < nr_range; i++)
+		set_var_mtrr_range(&var_state, range[i].start, range[i].end - range[i].start + 1);
+
+	/* Write the last range */
+	range_to_mtrr_with_hole(&var_state, 0);
+	printk(KERN_INFO "DONE variable MTRRs\n");
+	/* Clear out the extra MTRR's */
+	while (var_state.reg < num_var_ranges)
+		set_var_mtrr(var_state.reg++, 0, 0, 0, var_state.address_bits);
+}
+
+static int __init mtrr_cleanup(unsigned address_bits)
+{
+	unsigned long i, base, size, def, dummy;
+	mtrr_type type;
+	struct res_range range[RANGE_NUM];
+	int nr_range;
+
+	/* extra one for all 0 */
+	int num[MTRR_NUM_TYPES + 1];
+
+	if (!is_cpu(INTEL) || !enable_mtrr_cleanup)
+		return 0;
+	rdmsr(MTRRdefType_MSR, def, dummy);
+	def &= 0xff;
+	if (def != MTRR_TYPE_UNCACHABLE)
+		return 0;
+
+	/* check entries number */
+	memset(num, 0, sizeof(num));
+	for (i = 0; i < num_var_ranges; i++) {
+		mtrr_if->get(i, &base, &size, &type);
+		if (type >= MTRR_NUM_TYPES)
+			continue;
+		if (!size)
+			type = MTRR_NUM_TYPES;
+		num[type]++;
+	}
+
+	/* check if we got UC entries */
+	if (!num[MTRR_TYPE_UNCACHABLE])
+		return 0;
+
+	/* check if we only had WB and UC */
+	if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
+		num_var_ranges - num[MTRR_NUM_TYPES])
+		return 0;
+
+	/*
+	 * get WB ranges at first
+	 * assume BIOS don't give us overlapping WB entries
+	 * or add add_range?
+	 */
+	memset(range, 0, sizeof(range));
+	nr_range = 0;
+	for (i = 0; i < num_var_ranges; i++) {
+		mtrr_if->get(i, &base, &size, &type);
+		if (type != MTRR_TYPE_WRBACK)
+			continue;
+		range[nr_range].start = base;
+		range[nr_range].end = base + size - 1;
+		nr_range++;
+	}
+	printk(KERN_INFO "After WB checking\n");
+	for (i = 0; i < nr_range; i++)
+		printk(KERN_INFO "MTRR MAP PFN: %016lx - %016lx\n", range[i].start, range[i].end + 1);
+
+	/* take out UC ranges */
+	for (i = 0; i < num_var_ranges; i++) {
+		mtrr_if->get(i, &base, &size, &type);
+		if (type != MTRR_TYPE_UNCACHABLE)
+			continue;
+		if (!size)
+			continue;
+		subtract_range(range, base, base + size - 1);
+	}
+	/* get new range num */
+	nr_range = 0;
+	for (i = 0; i < RANGE_NUM; i++) {
+		if (!range[i].end)
+			continue;
+		nr_range++;
+	}
+	printk(KERN_INFO "After UC checking\n");
+	for (i = 0; i < nr_range; i++)
+		printk(KERN_INFO "MTRR MAP PFN: %016lx - %016lx\n", range[i].start, range[i].end + 1);
+
+	/* sort the ranges */
+	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+	printk(KERN_INFO "After sorting\n");
+	for (i = 0; i < nr_range; i++)
+		printk(KERN_INFO "MTRR MAP PFN: %016lx - %016lx\n", range[i].start, range[i].end + 1);
+
+	/* convert ranges to var ranges state */
+	x86_setup_var_mtrrs(range, nr_range, address_bits);
+
+	return 1;
+
+}
+
 static int disable_mtrr_trim;
 
 static int __init disable_mtrr_trim_setup(char *str)
@@ -729,18 +1069,21 @@ int __init mtrr_trim_uncached_memory(uns
  */
 void __init mtrr_bp_init(void)
 {
+	u32 phys_addr;
 	init_ifs();
 
+	phys_addr = 32;
+
 	if (cpu_has_mtrr) {
 		mtrr_if = &generic_mtrr_ops;
 		size_or_mask = 0xff000000;	/* 36 bits */
 		size_and_mask = 0x00f00000;
+		phys_addr = 36;
 
 		/* This is an AMD specific MSR, but we assume(hope?) that
 		   Intel will implement it to when they extend the address
 		   bus of the Xeon. */
 		if (cpuid_eax(0x80000000) >= 0x80000008) {
-			u32 phys_addr;
 			phys_addr = cpuid_eax(0x80000008) & 0xff;
 			/* CPUID workaround for Intel 0F33/0F34 CPU */
 			if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
@@ -758,6 +1101,7 @@ void __init mtrr_bp_init(void)
 			   don't support PAE */
 			size_or_mask = 0xfff00000;	/* 32 bits */
 			size_and_mask = 0;
+			phys_addr = 32;
 		}
 	} else {
 		switch (boot_cpu_data.x86_vendor) {
@@ -791,8 +1135,13 @@ void __init mtrr_bp_init(void)
 	if (mtrr_if) {
 		set_num_var_ranges();
 		init_table();
-		if (use_intel())
+		if (use_intel()) {
 			get_mtrr_state();
+
+			if (mtrr_cleanup(phys_addr))
+				mtrr_if->set_all();
+
+		}
 	}
 }
 
@@ -829,7 +1178,7 @@ static int __init mtrr_init_finialize(vo
 {
 	if (!mtrr_if)
 		return 0;
-	if (use_intel())
+	if (use_intel() && !enable_mtrr_cleanup)
 		mtrr_state_warn();
 	else {
 		/* The CPUs haven't MTRR and seem to not support SMP. They have
Index: linux-2.6/arch/x86/kernel/cpu/mtrr/mtrr.h
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/mtrr/mtrr.h
+++ linux-2.6/arch/x86/kernel/cpu/mtrr/mtrr.h
@@ -81,6 +81,8 @@ void set_mtrr_done(struct set_mtrr_conte
 void set_mtrr_cache_disable(struct set_mtrr_context *ctxt);
 void set_mtrr_prepare_save(struct set_mtrr_context *ctxt);
 
+void fill_mtrr_var_range(unsigned int index,
+		u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi);
 void get_mtrr_state(void);
 
 extern void set_mtrr_ops(struct mtrr_ops * ops);
Index: linux-2.6/Documentation/kernel-parameters.txt
===================================================================
--- linux-2.6.orig/Documentation/kernel-parameters.txt
+++ linux-2.6/Documentation/kernel-parameters.txt
@@ -595,6 +595,16 @@ and is between 256 and 4096 characters. 
 			See drivers/char/README.epca and
 			Documentation/digiepca.txt.
 
+	enable_mtrr_cleanup [X86]
+			By default the kernel will not touch mtrr. But we may
+			need adjust mtrr from continuous to discrete layout,
+			to make x server driver could add WB entry later. This
+			parameter enable that behavior, will touch MTRRs.
+
+	mtrr_chunk_size=nn[KMG] [X86]
+			used for mtrr cleanup. It is largest continous chunk
+			that could hold holes aka. UC entries.
+
 	disable_mtrr_trim [X86, Intel and AMD only]
 			By default the kernel will trim any uncacheable
 			memory out of your available memory pool based on

  parent reply	other threads:[~2008-04-28 19:45 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-28  6:37 [PATCH] x86: mtrr cleanup for converting continuous to discrete layout Yinghai Lu
2008-04-28  9:06 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v2 Yinghai Lu
2008-04-28 13:08   ` Ingo Molnar
2008-04-28 13:49     ` Arjan van de Ven
2008-04-28 15:28       ` Mika Fischer
2008-04-28  5:50         ` Arjan van de Ven
2008-04-28 16:01         ` Gabriel C
2008-04-28 16:28           ` Mika Fischer
2008-04-28 19:44   ` Yinghai Lu [this message]
2008-04-28 20:15     ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v3 Ingo Molnar
2008-04-28 20:18       ` Yinghai Lu
2008-04-28 20:29         ` Ingo Molnar
2008-04-28 20:16     ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v4 Yinghai Lu
2008-04-28 22:05       ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v5 Yinghai Lu
2008-04-28 22:36         ` Randy Dunlap
2008-04-28 22:47           ` Yinghai Lu
2008-04-29  2:42         ` Andrew Morton
2008-04-29  3:01           ` Yinghai Lu
     [not found]         ` <200804290157.30651.yhlu.kernel@gmail.com>
2008-04-29  8:59           ` [PATCH 2/2] x86: fix trimming e820 with MTRR holes Yinghai Lu
2008-04-29 11:35             ` Ingo Molnar
2008-04-29 17:18               ` Yinghai Lu
2008-04-29 17:20                 ` Yinghai Lu
2008-04-30  3:25             ` [PATCH] x86: fix trimming e820 with MTRR holes. - fix Yinghai Lu
2008-04-30 12:09               ` Ingo Molnar
2008-04-29  9:00         ` [PATCH 1/2] x86: mtrr cleanup for converting continuous to discrete layout v7 Yinghai Lu
2008-04-29  9:47           ` Gabriel C
2008-04-29 10:30             ` Yinghai Lu
2008-04-29 10:56               ` Yinghai Lu
2008-04-29 11:26                 ` Ingo Molnar
2008-04-29 11:51                 ` Gabriel C
2008-04-29 17:11                   ` Yinghai Lu
2008-04-29 20:25                     ` Gabriel C
2008-04-29 21:49                       ` Yinghai Lu
2008-04-29 23:56                         ` Gabriel C
2008-04-30  0:06                           ` Gabriel C
2008-04-30  0:38                             ` Yinghai Lu
2008-04-30  1:02                               ` Gabriel C
2008-04-30  3:00                                 ` Yinghai Lu
2008-04-30  3:29                                   ` Yinghai Lu
2008-04-30  4:12                                     ` Gabriel C
2008-04-30  4:25                                       ` Yinghai Lu
2008-04-30 12:04                                         ` Gabriel C
2008-04-30 16:26                                           ` Yinghai Lu
2008-04-30  0:13                           ` Yinghai Lu
2008-04-29 10:52           ` [PATCH 1/2] x86: mtrr cleanup for converting continuous to discrete layout v8 Yinghai Lu
2008-04-29 13:07             ` Ingo Molnar
2008-04-29 17:25               ` Yinghai Lu
2008-04-29 20:46             ` Randy Dunlap
2008-04-29 21:54               ` Yinghai Lu
2008-04-30  3:25             ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v8 - fix Yinghai Lu
2008-04-30 12:09               ` Ingo Molnar
2008-05-01  8:00               ` [PATCH] x86: mtrr cleanup for converting continuous to discrete - auto detect Yinghai Lu
2008-05-01 11:45                 ` Gabriel C
2008-05-02  0:06                   ` Yinghai Lu
2008-05-02  0:29                     ` Gabriel C
2008-05-02  0:35                       ` Yinghai Lu
2008-05-02  1:18                         ` Gabriel C
2008-05-02  1:55                           ` Yinghai Lu
2008-05-01 12:09                 ` Mika Fischer
2008-05-01 16:35                   ` Yinghai Lu
2008-05-01 16:59                     ` Mika Fischer
2008-05-01 17:40                       ` Yinghai Lu
2008-05-01 15:09                 ` Randy Dunlap
2008-05-01 16:38                   ` Yinghai Lu
2008-05-01 18:57                 ` [PATCH] x86: mtrr cleanup for converting continuous to discrete - auto detect v2 Yinghai Lu
2008-05-01 19:42                   ` H. Peter Anvin
2008-05-01 21:02                     ` Yinghai Lu
2008-05-01 21:10                       ` H. Peter Anvin
2008-05-01 21:20                         ` Yinghai Lu
2008-05-01 21:26                           ` H. Peter Anvin
2008-05-01 21:31                             ` Yinghai Lu
2008-05-01 21:33                               ` H. Peter Anvin
2008-05-01 21:44                                 ` Yinghai Lu
2008-05-01 21:49                                   ` H. Peter Anvin
2008-05-01 22:52                                     ` Yinghai Lu
2008-05-01 22:57                                       ` H. Peter Anvin
2008-05-01 23:10                                         ` Yinghai Lu
2008-05-02  0:52                   ` [PATCH] x86: mtrr cleanup for converting continuous to discrete - auto detect v3 Yinghai Lu
2008-05-02  9:40                     ` [PATCH] x86: mtrr cleanup for converting continuous to discrete - auto detect v4 Yinghai Lu
2008-04-29 19:00         ` [PATCH] x86: mtrr cleanup for converting continuous to discrete layout v5 Eric W. Biederman
2008-04-29 20:04           ` Yinghai Lu
2008-04-29 20:29             ` Eric W. Biederman
2008-04-29 21:57               ` Yinghai Lu
2008-04-29 22:09                 ` Ingo Molnar
2008-04-29 22:18                   ` Yinghai Lu
2008-04-29 22:14                 ` Eric W. Biederman
2008-04-29 22:54                   ` Thomas Gleixner
2008-04-30  1:16                     ` Eric W. Biederman
2008-04-30  9:57                       ` Alan Cox

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=200804281244.56938.yhlu.kernel@gmail.com \
    --to=yhlu.kernel.send@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mika.fischer@zoopnet.de \
    --cc=mingo@elte.hu \
    --cc=nix.or.die@googlemail.com \
    --cc=tglx@linutronix.de \
    --cc=yhlu.kernel@gmail.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.