From: Thomas Gleixner <tglx@linutronix.de>
To: Andrew Morton <akpm@osdl.org>
Cc: LKML <linux-kernel@vger.kernel.org>, Ingo Molnar <mingo@elte.hu>,
John Stultz <johnstul@us.ibm.com>,
Arjan van de Veen <arjan@infradead.org>,
Roman Zippel <zippel@linux-m68k.org>
Subject: [patch 35/46] tick-management: broadcast functionality
Date: Tue, 23 Jan 2007 22:01:32 -0000 [thread overview]
Message-ID: <20070123211208.389447000@localhost.localdomain> (raw)
In-Reply-To: 20070123211159.178138000@localhost.localdomain
[-- Attachment #1: tick-management-broadcast-support.patch --]
[-- Type: text/plain, Size: 13741 bytes --]
From: Thomas Gleixner <tglx@linutronix.de>
From: Ingo Molnar <mingo@elte.hu>
Add broadcast functionality, so per cpu clock event devices can be
registered as dummy devices or switched from/to broadcast on demand.
The broadcast function distributes the events via the broadcast
function of the clock event device. This is primarily designed to
replace the switch apic timer to / from IPI in power states, where the
apic stops.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/time/Makefile | 5
kernel/time/tick-broadcast.c | 258 +++++++++++++++++++++++++++++++++++++++++++
kernel/time/tick-common.c | 63 +++++++---
kernel/time/tick-internal.h | 74 ++++++++++++
4 files changed, 378 insertions(+), 22 deletions(-)
Index: linux-2.6.20-rc4-mm1-bo/kernel/time/Makefile
===================================================================
--- linux-2.6.20-rc4-mm1-bo.orig/kernel/time/Makefile
+++ linux-2.6.20-rc4-mm1-bo/kernel/time/Makefile
@@ -1,4 +1,5 @@
obj-y += ntp.o clocksource.o jiffies.o
-obj-$(CONFIG_GENERIC_CLOCKEVENTS) += clockevents.o
-obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS) += clockevents.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += tick-broadcast.o
Index: linux-2.6.20-rc4-mm1-bo/kernel/time/tick-broadcast.c
===================================================================
--- /dev/null
+++ linux-2.6.20-rc4-mm1-bo/kernel/time/tick-broadcast.c
@@ -0,0 +1,258 @@
+/*
+ * linux/kernel/time/tick-broadcast.c
+ *
+ * This file contains functions which emulate a local clock-event
+ * device via a broadcast event source.
+ *
+ * Copyright(C) 2005-2006, Thomas Gleixner <tglx@linutronix.de>
+ * Copyright(C) 2005-2007, Red Hat, Inc., Ingo Molnar
+ * Copyright(C) 2006-2007, Timesys Corp., Thomas Gleixner
+ *
+ * This code is licenced under the GPL version 2. For details see
+ * kernel-base/COPYING.
+ */
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/hrtimer.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
+#include <linux/profile.h>
+#include <linux/sched.h>
+#include <linux/tick.h>
+
+#include "tick-internal.h"
+
+/*
+ * Broadcast support for broken x86 hardware, where the local apic
+ * timer stops in C3 state.
+ */
+
+struct tick_device tick_broadcast_device;
+static cpumask_t tick_broadcast_mask;
+DEFINE_SPINLOCK(tick_broadcast_lock);
+
+/*
+ * Start the device in periodic mode
+ */
+static void tick_broadcast_start_periodic(struct clock_event_device *bc)
+{
+ if (bc && bc->mode == CLOCK_EVT_MODE_SHUTDOWN)
+ tick_setup_periodic(bc, 1);
+}
+
+/*
+ * Check, if the device can be utilized as broadcast device:
+ */
+int tick_check_broadcast_device(struct clock_event_device *dev)
+{
+ if (tick_broadcast_device.evtdev ||
+ (dev->features & CLOCK_EVT_FEAT_C3STOP))
+ return 0;
+
+ clockevents_exchange_device(NULL, dev);
+ tick_broadcast_device.evtdev = dev;
+ if (!cpus_empty(tick_broadcast_mask))
+ tick_broadcast_start_periodic(dev);
+ return 1;
+}
+
+/*
+ * Check, if the device is the broadcast device
+ */
+int tick_is_broadcast_device(struct clock_event_device *dev)
+{
+ return (dev && tick_broadcast_device.evtdev == dev);
+}
+
+/*
+ * Check, if the device is disfunctional and a place holder, which
+ * needs to be handled by the broadcast device.
+ */
+int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&tick_broadcast_lock, flags);
+
+ /*
+ * Devices might be registered with both periodic and oneshot
+ * mode disabled. This signals, that the device needs to be
+ * operated from the broadcast device and is a placeholder for
+ * the cpu local device.
+ */
+ if (!tick_device_is_functional(dev)) {
+ dev->event_handler = tick_handle_periodic;
+ cpu_set(cpu, tick_broadcast_mask);
+ tick_broadcast_start_periodic(tick_broadcast_device.evtdev);
+ ret = 1;
+ }
+
+ spin_unlock_irqrestore(&tick_broadcast_lock, flags);
+ return ret;
+}
+
+/*
+ * Broadcast the event to the cpus, which are set in the mask
+ */
+int tick_do_broadcast(cpumask_t mask)
+{
+ int ret = 0, cpu = smp_processor_id();
+ struct tick_device *td;
+
+ /*
+ * Check, if the current cpu is in the mask
+ */
+ if (cpu_isset(cpu, mask)) {
+ cpu_clear(cpu, mask);
+ td = &per_cpu(tick_cpu_device, cpu);
+ td->evtdev->event_handler(td->evtdev);
+ ret = 1;
+ }
+
+ if (!cpus_empty(mask)) {
+ /*
+ * It might be necessary to actually check whether the devices
+ * have different broadcast functions. For now, just use the
+ * one of the first device. This works as long as we have this
+ * misfeature only on x86 (lapic)
+ */
+ cpu = first_cpu(mask);
+ td = &per_cpu(tick_cpu_device, cpu);
+ td->evtdev->broadcast(mask);
+ ret = 1;
+ }
+ return ret;
+}
+
+/*
+ * Periodic broadcast:
+ * - invoke the broadcast handlers
+ */
+static void tick_do_periodic_broadcast(void)
+{
+ cpumask_t mask;
+
+ spin_lock(&tick_broadcast_lock);
+
+ cpus_and(mask, cpu_online_map, tick_broadcast_mask);
+ tick_do_broadcast(mask);
+
+ spin_unlock(&tick_broadcast_lock);
+}
+
+/*
+ * Event handler for periodic broadcast ticks
+ */
+static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
+{
+ tick_do_periodic_broadcast();
+
+ /*
+ * The device is in periodic mode. No reprogramming necessary:
+ */
+ if (dev->mode == CLOCK_EVT_MODE_PERIODIC)
+ return;
+
+ /*
+ * Setup the next period for devices, which do not have
+ * periodic mode:
+ */
+ for (;;) {
+ ktime_t next = ktime_add(dev->next_event, tick_period);
+
+ if (!clockevents_program_event(dev, next))
+ return;
+ tick_do_periodic_broadcast();
+ }
+}
+
+/*
+ * Powerstate information: The system enters/leaves a state, where
+ * affected devices might stop
+ */
+static void tick_do_broadcast_on_off(void *why)
+{
+ struct clock_event_device *bc, *dev;
+ struct tick_device *td;
+ unsigned long flags, *reason = why;
+ int cpu;
+
+ spin_lock_irqsave(&tick_broadcast_lock, flags);
+
+ cpu = smp_processor_id();
+ td = &per_cpu(tick_cpu_device, cpu);
+ dev = td->evtdev;
+ bc = tick_broadcast_device.evtdev;
+
+ /*
+ * Is the device in broadcast mode forever or is it not
+ * affected by the powerstate ?
+ */
+ if (!dev || !tick_device_is_functional(dev) ||
+ !(dev->features & CLOCK_EVT_FEAT_C3STOP))
+ goto out;
+
+ if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_ON) {
+ if (!cpu_isset(cpu, tick_broadcast_mask)) {
+ cpu_set(cpu, tick_broadcast_mask);
+ if (td->mode == TICKDEV_MODE_PERIODIC)
+ clockevents_set_mode(dev,
+ CLOCK_EVT_MODE_SHUTDOWN);
+ }
+ } else {
+ if (cpu_isset(cpu, tick_broadcast_mask)) {
+ cpu_clear(cpu, tick_broadcast_mask);
+ if (td->mode == TICKDEV_MODE_PERIODIC)
+ tick_setup_periodic(dev, 0);
+ }
+ }
+
+ if (cpus_empty(tick_broadcast_mask))
+ clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
+ else {
+ if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
+ tick_broadcast_start_periodic(bc);
+ }
+out:
+ spin_unlock_irqrestore(&tick_broadcast_lock, flags);
+}
+
+/*
+ * Powerstate information: The system enters/leaves a state, where
+ * affected devices might stop.
+ */
+void tick_broadcast_on_off(unsigned long reason, int *oncpu)
+{
+ int cpu = get_cpu();
+
+ if (cpu == *oncpu)
+ tick_do_broadcast_on_off(&reason);
+ else
+ smp_call_function_single(*oncpu, tick_do_broadcast_on_off,
+ &reason, 1, 1);
+ put_cpu();
+}
+
+/*
+ * Set the periodic handler depending on broadcast on/off
+ */
+void tick_set_periodic_handler(struct clock_event_device *dev, int broadcast)
+{
+ if (!broadcast)
+ dev->event_handler = tick_handle_periodic;
+ else
+ dev->event_handler = tick_handle_periodic_broadcast;
+}
+
+/*
+ * Called with irqs disabled
+ */
+void tick_do_resume(int cpu)
+{
+ unsigned long reason;
+
+ reason = cpu_isset(cpu, tick_broadcast_mask) ?
+ CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
+ tick_do_broadcast_on_off(&reason);
+}
Index: linux-2.6.20-rc4-mm1-bo/kernel/time/tick-common.c
===================================================================
--- linux-2.6.20-rc4-mm1-bo.orig/kernel/time/tick-common.c
+++ linux-2.6.20-rc4-mm1-bo/kernel/time/tick-common.c
@@ -20,17 +20,19 @@
#include <linux/sched.h>
#include <linux/tick.h>
+#include "tick-internal.h"
+
/*
* Tick devices
*/
-static DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
+DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
/*
* Tick next event: keeps track of the tick time
*/
-static ktime_t tick_next_period;
-static ktime_t tick_period;
+ktime_t tick_next_period;
+ktime_t tick_period;
static int tick_do_timer_cpu = -1;
-static DEFINE_SPINLOCK(tick_device_lock);
+DEFINE_SPINLOCK(tick_device_lock);
/*
* Periodic tick
@@ -78,9 +80,13 @@ void tick_handle_periodic(struct clock_e
/*
* Setup the device for a periodic tick
*/
-void tick_setup_periodic(struct clock_event_device *dev)
+void tick_setup_periodic(struct clock_event_device *dev, int broadcast)
{
- dev->event_handler = tick_handle_periodic;
+ tick_set_periodic_handler(dev, broadcast);
+
+ /* Broadcast setup ? */
+ if (!tick_device_is_functional(dev))
+ return;
if (dev->features & CLOCK_EVT_FEAT_PERIODIC) {
clockevents_set_mode(dev, CLOCK_EVT_MODE_PERIODIC);
@@ -145,6 +151,15 @@ static void tick_setup_device(struct tic
if (!cpus_equal(newdev->cpumask, cpumask))
irq_set_affinity(newdev->irq, cpumask);
+ /*
+ * When global broadcasting is active, check if the current
+ * device is registered as a placeholder for broadcast mode.
+ * This allows us to handle this x86 misfeature in a generic
+ * way.
+ */
+ if (tick_device_uses_broadcast(newdev, cpu))
+ return;
+
if (td->mode == TICKDEV_MODE_PERIODIC)
tick_setup_periodic(newdev, 0);
}
@@ -197,31 +212,34 @@ static int tick_check_new_device(struct
* Check the rating
*/
if (curdev->rating >= newdev->rating)
- goto out;
+ goto out_bc;
}
/*
* Replace the eventually existing device by the new
- * device.
+ * device. If the current device is the broadcast device, do
+ * not give it back to the clockevents layer !
*/
+ if (tick_is_broadcast_device(curdev)) {
+ clockevents_set_mode(curdev, CLOCK_EVT_MODE_SHUTDOWN);
+ curdev = NULL;
+ }
clockevents_exchange_device(curdev, newdev);
tick_setup_device(td, newdev, cpu, cpumask);
- ret = NOTIFY_STOP;
-out:
spin_unlock_irqrestore(&tick_device_lock, flags);
- return ret;
-}
+ return NOTIFY_STOP;
-/*
- * Called with irqs disabled
- */
-static inline void tick_do_resume(int cpu)
-{
- struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
+out_bc:
+ /*
+ * Can the new device be used as a broadcast device ?
+ */
+ if (tick_check_broadcast_device(newdev))
+ ret = NOTIFY_STOP;
+out:
+ spin_unlock_irqrestore(&tick_device_lock, flags);
- if (td->mode == TICKDEV_MODE_PERIODIC)
- tick_setup_periodic(td->evtdev, 0);
+ return ret;
}
/*
@@ -247,6 +265,11 @@ static int tick_notify(struct notifier_b
case CLOCK_EVT_NOTIFY_ADD:
return tick_check_new_device(dev);
+ case CLOCK_EVT_NOTIFY_BROADCAST_ON:
+ case CLOCK_EVT_NOTIFY_BROADCAST_OFF:
+ tick_broadcast_on_off(reason, dev);
+ break;
+
case CLOCK_EVT_NOTIFY_RESUME:
tick_resume();
break;
Index: linux-2.6.20-rc4-mm1-bo/kernel/time/tick-internal.h
===================================================================
--- /dev/null
+++ linux-2.6.20-rc4-mm1-bo/kernel/time/tick-internal.h
@@ -0,0 +1,74 @@
+/*
+ * tick internal variable and functions used by low/high res code
+ */
+DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
+extern spinlock_t tick_device_lock;
+extern ktime_t tick_next_period;
+extern ktime_t tick_period;
+
+extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
+extern void tick_handle_periodic(struct clock_event_device *dev);
+
+/*
+ * Broadcasting support
+ */
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+extern int tick_do_broadcast(cpumask_t mask);
+extern struct tick_device tick_broadcast_device;
+extern spinlock_t tick_broadcast_lock;
+
+extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
+extern int tick_check_broadcast_device(struct clock_event_device *dev);
+extern int tick_is_broadcast_device(struct clock_event_device *dev);
+extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
+
+extern void
+tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
+extern void tick_do_resume(int cpu);
+
+#else /* !BROADCAST */
+
+static inline int tick_check_broadcast_device(struct clock_event_device *dev)
+{
+ return 0;
+}
+
+static inline int tick_is_broadcast_device(struct clock_event_device *dev)
+{
+ return 0;
+}
+static inline int tick_device_uses_broadcast(struct clock_event_device *dev,
+ int cpu)
+{
+ return 0;
+}
+static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
+static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
+
+/*
+ * Set the periodic handler in non broadcast mode
+ */
+static inline void tick_set_periodic_handler(struct clock_event_device *dev,
+ int broadcast)
+{
+ dev->event_handler = tick_handle_periodic;
+}
+/*
+ * Called with irqs disabled
+ */
+static inline void tick_do_resume(int cpu)
+{
+ struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
+
+ if (td->mode == TICKDEV_MODE_PERIODIC)
+ tick_setup_periodic(td->evtdev, 0);
+}
+#endif /* !BROADCAST */
+
+/*
+ * Check, if the device is functional or a dummy for broadcast
+ */
+static inline int tick_device_is_functional(struct clock_event_device *dev)
+{
+ return !(dev->features & CLOCK_EVT_FEAT_DUMMY);
+}
--
next prev parent reply other threads:[~2007-01-23 22:08 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-23 22:00 [patch 00/46] High resolution timer / dynamic tick update Thomas Gleixner
2007-01-23 22:00 ` [patch 01/46] Add irq flag to disable balancing for an interrupt Thomas Gleixner
2007-01-23 22:00 ` [patch 02/46] Add a functions to handle interrupt affinity setting Thomas Gleixner
2007-01-23 22:00 ` [patch 03/46] [RFC] HZ free ntp Thomas Gleixner
2007-01-23 22:00 ` [patch 04/46] Uninline jiffies.h functions Thomas Gleixner
2007-01-23 22:01 ` [patch 05/46] Thomas Gleixner
2007-01-23 22:01 ` [patch 06/46] Fix timeout overflow with jiffies Thomas Gleixner
2007-01-23 22:01 ` [patch 07/46] GTOD: persistent clock support Thomas Gleixner
2007-01-23 22:01 ` [patch 08/46] i386: use GTOD " Thomas Gleixner
2007-01-23 22:01 ` [patch 09/46] i386 Remove useless code in tsc.c Thomas Gleixner
2007-01-23 22:01 ` [patch 10/46] Simplify the registration of clocksources Thomas Gleixner
2007-01-23 22:01 ` [patch 11/46] x86: rewrite SMP TSC sync code Thomas Gleixner
2007-01-23 22:01 ` [patch 12/46] clocksource: replace is_continuous by a flag field Thomas Gleixner
2007-01-24 11:23 ` [patch] clocksource: fixup is_continous changes in vmitime.c Ingo Molnar
2007-01-24 11:53 ` Thomas Gleixner
2007-01-23 22:01 ` [patch 13/46] clocksource: fixup is_continous changes on ARM Thomas Gleixner
2007-01-23 22:01 ` [patch 14/46] clocksource: fixup is_continous changes on AVR32 Thomas Gleixner
2007-01-23 22:01 ` [patch 15/46] clocksource: fixup is_continous changes on S390 Thomas Gleixner
2007-01-23 22:01 ` [patch 16/46] clocksource: fixup is_continous changes on MIPS Thomas Gleixner
2007-01-23 22:01 ` [patch 17/46] clocksource: Remove the update callback Thomas Gleixner
2007-01-23 22:01 ` [patch 18/46] clocksource: Add verification (watchdog) helper Thomas Gleixner
2007-01-24 15:42 ` [patch] clocksource: add verification (watchdog) helper, fix Ingo Molnar
2007-01-23 22:01 ` [patch 19/46] Mark TSC on GeodeLX reliable Thomas Gleixner
2007-01-23 22:01 ` [patch 20/46] uninline irq_enter() Thomas Gleixner
2007-01-23 22:01 ` [patch 21/46] Fix cascade lookup of next_timer_interrupt Thomas Gleixner
2007-01-23 22:01 ` [patch 22/46] Extend next_timer_interrupt() to use a reference jiffie Thomas Gleixner
2007-01-23 22:01 ` [patch 23/46] hrtimers: namespace and enum cleanup Thomas Gleixner
2007-01-23 22:01 ` [patch 24/46] hrtimers: namespace and enum cleanup vs. git-input Thomas Gleixner
2007-01-23 22:01 ` [patch 25/46] hrtimers: cleanup locking Thomas Gleixner
2007-01-23 22:01 ` [patch 26/46] hrtimers; add state tracking Thomas Gleixner
2007-01-23 22:01 ` [patch 27/46] hrtimers: clean up callback tracking Thomas Gleixner
2007-01-23 22:01 ` [patch 28/46] hrtimers: move and add documentation Thomas Gleixner
2007-01-23 22:01 ` [patch 29/46] ACPI: fix missing include for UP Thomas Gleixner
2007-01-23 22:01 ` [patch 30/46] ACPI keep track of timer broadcasting Thomas Gleixner
2007-01-23 22:01 ` [patch 31/46] Allow early access to the power management timer Thomas Gleixner
2007-01-23 22:01 ` [patch 32/46] i386, apic: clean up the APIC code Thomas Gleixner
2007-01-23 22:01 ` [patch 33/46] clockevents: add core functionality Thomas Gleixner
2007-01-23 22:01 ` [patch 34/46] tick-management: " Thomas Gleixner
2007-01-23 22:01 ` Thomas Gleixner [this message]
2007-01-23 22:01 ` [patch 36/46] tick-management: dyntick / highres functionality Thomas Gleixner
2007-01-28 2:03 ` [PATCH] high_res_timers: precisely update_process_times; " Karsten Wiese
2007-01-23 22:01 ` [patch 37/46] clockevents: i383 drivers Thomas Gleixner
2007-01-23 22:01 ` [patch 38/46] i386 rework local apic timer calibration Thomas Gleixner
2007-01-23 22:01 ` [patch 39/46] i386 prepare for dyntick Thomas Gleixner
2007-01-23 22:01 ` [patch 40/46] i386 prepare nmi watchdog for dynticks Thomas Gleixner
2007-01-23 22:01 ` [patch 41/46] i386: enable dynticks in kconfig Thomas Gleixner
2007-01-23 22:01 ` [patch 42/46] hrtimers: add high resolution timer support Thomas Gleixner
2007-01-23 22:01 ` [patch 43/46] hrtimers: prevent possible itimer DoS Thomas Gleixner
2007-01-23 22:01 ` [patch 44/46] Add debugging feature /proc/timer_stat Thomas Gleixner
2007-01-23 22:01 ` [patch 45/46] Add debugging feature /proc/timer_list Thomas Gleixner
2007-01-23 22:01 ` [patch 46/46] Add SysRq-Q to print timer_list debug info Thomas Gleixner
2007-01-24 2:16 ` [patch 00/46] High resolution timer / dynamic tick update Daniel Walker
2007-01-24 2:23 ` Andrew Morton
2007-01-24 3:25 ` Daniel Walker
2007-01-24 7:07 ` Ingo Molnar
2007-01-24 9:30 ` Daniel Walker
2007-01-24 9:51 ` Ingo Molnar
2007-01-24 10:23 ` Daniel Walker
2007-01-24 10:29 ` Ingo Molnar
2007-01-24 10:53 ` Daniel Walker
2007-01-24 11:04 ` Ingo Molnar
2007-01-24 11:13 ` Thomas Gleixner
2007-01-24 15:53 ` Daniel Walker
[not found] ` <20070124160046.GA24798@elte.hu>
2007-01-24 17:21 ` Daniel Walker
[not found] ` <1169655076.19471.241.camel@imap.mvista.com>
2007-01-24 19:38 ` Ingo Molnar
2007-01-24 20:09 ` Daniel Walker
2007-01-24 20:13 ` Ingo Molnar
2007-01-24 19:57 ` john stultz
2007-01-24 20:51 ` Daniel Walker
2007-01-24 21:23 ` john stultz
2007-01-24 21:37 ` Daniel Walker
2007-01-25 6:10 ` Ingo Molnar
2007-01-25 6:37 ` Ingo Molnar
2007-01-25 6:32 ` Ingo Molnar
2007-01-25 16:38 ` Daniel Walker
2007-01-28 2:17 ` Andrew Morton
2007-01-29 21:31 ` john stultz
2007-01-29 21:45 ` john stultz
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=20070123211208.389447000@localhost.localdomain \
--to=tglx@linutronix.de \
--cc=akpm@osdl.org \
--cc=arjan@infradead.org \
--cc=johnstul@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=zippel@linux-m68k.org \
/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.