From: "Zhang, Yanmin" <yanmin_zhang@linux.intel.com>
To: Ingo Molnar <mingo@elte.hu>
Cc: Joerg Roedel <joro@8bytes.org>,
Jes Sorensen <Jes.Sorensen@redhat.com>,
KVM General <kvm@vger.kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Avi Kivity <avi@redhat.com>, Zachary Amsden <zamsden@redhat.com>,
Gleb Natapov <gleb@redhat.com>,
ming.m.lin@intel.com
Subject: Re: KVM PMU virtualization
Date: Tue, 02 Mar 2010 15:09:06 +0800 [thread overview]
Message-ID: <1267513746.1726.104.camel@localhost> (raw)
In-Reply-To: <20100226091732.GI15885@elte.hu>
On Fri, 2010-02-26 at 10:17 +0100, Ingo Molnar wrote:
> * Joerg Roedel <joro@8bytes.org> wrote:
>
> > On Fri, Feb 26, 2010 at 10:55:17AM +0800, Zhang, Yanmin wrote:
> > > On Thu, 2010-02-25 at 18:34 +0100, Joerg Roedel wrote:
> > > > On Thu, Feb 25, 2010 at 04:04:28PM +0100, Jes Sorensen wrote:
> > > >
> > > > > 1) Add support to perf to allow it to monitor a KVM guest from the
> > > > > host.
> > > >
> > > > This shouldn't be a big problem. The PMU of AMD Fam10 processors can be
> > > > configured to count only when in guest mode. Perf needs to be aware of
> > > > that and fetch the rip from a different place when monitoring a guest.
> >
> > > The idea is we want to measure both host and guest at the same time, and
> > > compare all the hot functions fairly.
> >
> > So you want to measure while the guest vcpu is running and the vmexit
> > path of that vcpu (including qemu userspace part) together? The
> > challenge here is to find out if a performance event originated in guest
> > mode or in host mode.
> > But we can check for that in the nmi-protected part of the vmexit path.
>
> As far as instrumentation goes, virtualization is simply another 'PID
> dimension' of measurement.
>
> Today we can isolate system performance measurements/events to the following
> domains:
>
> - per system
> - per cpu
> - per task
>
> ( Note that PowerPC already supports certain sorts of 'hypervisor/kernel/user'
> domain separation, and we have some ABI details for all that but it's by no
> means complete. Anton is using the PowerPC bits AFAIK, so it already works
> to a certain degree. )
>
> When extending measurements to KVM, we want two things:
>
> - user friendliness: instead of having to check 'ps' and figure out which
> Qemu thread is the KVM thread we want to profile, just give a convenience
> namespace to access guest profiling info. -G ought to map to the first
> currently running KVM guest it can find. (which would match like 90% of the
> cases) - etc. No ifs and when. If 'perf kvm top' doesnt show something
> useful by default the whole effort is for naught.
>
> - Extend core facilities and enable the following measurement dimensions:
>
> host-kernel-space
> host-user-space
> guest-kernel-space
> guest-user-space
>
> on a per guest basis. We want to be able to measure just what the guest
> does, and we want to be able to measure just what the host does.
>
> Some of this the hardware helps us with (say only measuring host kernel
> events is possible), some has to be done by fiddling with event
> enable/disable at vm-exit / vm-entry time.
>
> My suggestion, as always, would be to start very simple and very minimal:
>
> Enable 'perf kvm top' to show guest overhead. Use the exact same kernel image
> both as a host and as guest (for testing), to not have to deal with the symbol
> space transport problem initially. Enable 'perf kvm record' to only record
> guest events by default. Etc.
>
> This alone will be a quite useful result already - and gives a basis for
> further work. No need to spend months to do the big grand design straight
> away, all of this can be done gradually and in the order of usefulness - and
> you'll always have something that actually works (and helps your other KVM
> projects) along the way.
It took me for a couple of hours to read the emails on the topic.
Based on above idea, I worked out a prototype which is ugly, but does work
with top/record when both guest side and host side use the same kernel image,
while compiling most needed modules into kernel directly..
The commands are:
perf kvm top
perf kvm record
perf kvm report
They just collect guest kernel hot functions.
>
> [ And, as so often, once you walk that path, that grand scheme you are
> thinking about right now might easily become last year's really bad idea ;-) ]
>
> So please start walking the path and experience the challenges first-hand.
With my patch, I collected dbench data on Nehalem machine (2*4*2 logical cpu).
1) Vanilla host kernel (6G memory):
------------------------------------------------------------------------------------------------------------------------
PerfTop: 15491 irqs/sec kernel:93.6% [1000Hz cycles], (all, 16 CPUs)
------------------------------------------------------------------------------------------------------------------------
samples pcnt function DSO
_______ _____ _______________________________ ________________________________________
99376.00 40.5% ext3_test_allocatable /lib/modules/2.6.33-kvmymz/build/vmlinux
41239.00 16.8% bitmap_search_next_usable_block /lib/modules/2.6.33-kvmymz/build/vmlinux
7019.00 2.9% __ticket_spin_lock /lib/modules/2.6.33-kvmymz/build/vmlinux
5350.00 2.2% copy_user_generic_string /lib/modules/2.6.33-kvmymz/build/vmlinux
5208.00 2.1% do_get_write_access /lib/modules/2.6.33-kvmymz/build/vmlinux
4484.00 1.8% journal_dirty_metadata /lib/modules/2.6.33-kvmymz/build/vmlinux
4078.00 1.7% ext3_free_blocks_sb /lib/modules/2.6.33-kvmymz/build/vmlinux
3856.00 1.6% ext3_new_blocks /lib/modules/2.6.33-kvmymz/build/vmlinux
3485.00 1.4% journal_get_undo_access /lib/modules/2.6.33-kvmymz/build/vmlinux
2803.00 1.1% ext3_try_to_allocate /lib/modules/2.6.33-kvmymz/build/vmlinux
2241.00 0.9% __find_get_block /lib/modules/2.6.33-kvmymz/build/vmlinux
1957.00 0.8% find_revoke_record /lib/modules/2.6.33-kvmymz/build/vmlinux
2) guest os: start one guest os with 4GB memory.
------------------------------------------------------------------------------------------------------------------------
PerfTop: 827 irqs/sec kernel: 0.0% [1000Hz cycles], (all, 16 CPUs)
------------------------------------------------------------------------------------------------------------------------
samples pcnt function DSO
_______ _____ _______________________________ ________________________________________
41701.00 28.1% __ticket_spin_lock /lib/modules/2.6.33-kvmymz/build/vmlinux
33843.00 22.8% ext3_test_allocatable /lib/modules/2.6.33-kvmymz/build/vmlinux
16862.00 11.4% bitmap_search_next_usable_block /lib/modules/2.6.33-kvmymz/build/vmlinux
3278.00 2.2% native_flush_tlb_others /lib/modules/2.6.33-kvmymz/build/vmlinux
3200.00 2.2% copy_user_generic_string /lib/modules/2.6.33-kvmymz/build/vmlinux
3009.00 2.0% do_get_write_access /lib/modules/2.6.33-kvmymz/build/vmlinux
2834.00 1.9% journal_dirty_metadata /lib/modules/2.6.33-kvmymz/build/vmlinux
1965.00 1.3% journal_get_undo_access /lib/modules/2.6.33-kvmymz/build/vmlinux
1907.00 1.3% ext3_new_blocks /lib/modules/2.6.33-kvmymz/build/vmlinux
1790.00 1.2% ext3_free_blocks_sb /lib/modules/2.6.33-kvmymz/build/vmlinux
1741.00 1.2% find_revoke_record /lib/modules/2.6.33-kvmymz/build/vmlinux
With vanilla host kernel, perf top data is stable and spinlock doesn't take too much cpu time.
With guest os, __ticket_spin_lock consumes 28% cpu time, and sometimes it fluctuates between 9%~28%.
Another interesting finding is aim7. If I start aim7 on tmpfs testing in guest os with 1GB memory,
the login hangs and cpu is busy. With the new patch, I could check what happens in guest os, where
spinlock is busy and kernel is shrinking memory mostly from slab.
--- linux-2.6.33/arch/x86/kernel/cpu/perf_event.c 2010-02-25 02:52:17.000000000 +0800
+++ linux-2.6.33_perfkvm/arch/x86/kernel/cpu/perf_event.c 2010-03-01 15:57:51.672990615 +0800
@@ -1621,6 +1621,7 @@ static void intel_pmu_drain_bts_buffer(s
struct perf_event_header header;
struct perf_sample_data data;
struct pt_regs regs;
+ int ret;
if (!event)
return;
@@ -1647,7 +1648,9 @@ static void intel_pmu_drain_bts_buffer(s
* We will overwrite the from and to address before we output
* the sample.
*/
- perf_prepare_sample(&header, &data, event, ®s);
+ ret = perf_prepare_sample(&header, &data, event, ®s);
+ if (ret)
+ return;
if (perf_output_begin(&handle, event,
header.size * (top - at), 1, 1))
--- linux-2.6.33/arch/x86/kvm/vmx.c 2010-02-25 02:52:17.000000000 +0800
+++ linux-2.6.33_perfkvm/arch/x86/kvm/vmx.c 2010-03-02 10:21:57.588586179 +0800
@@ -26,6 +26,7 @@
#include <linux/sched.h>
#include <linux/moduleparam.h>
#include <linux/ftrace_event.h>
+#include <linux/perf_event.h>
#include "kvm_cache_regs.h"
#include "x86.h"
@@ -3553,8 +3554,19 @@ static void vmx_complete_interrupts(stru
/* We need to handle NMIs before interrupts are enabled */
if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
- (exit_intr_info & INTR_INFO_VALID_MASK))
+ (exit_intr_info & INTR_INFO_VALID_MASK)) {
+ u64 rip = vmcs_readl(GUEST_RIP);
+ int user_mode = vmcs_read16(GUEST_CS_SELECTOR);
+
+#ifdef CONFIG_X86_32
+ user_mode = (user_mode & SEGMENT_RPL_MASK) == USER_RPL;
+#else
+ user_mode = !!(user_mode & 3);
+#endif
+ perf_save_virt_ip(user_mode, rip);
asm("int $2");
+ perf_reset_virt_ip();
+ }
idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
--- linux-2.6.33/include/linux/perf_event.h 2010-02-25 02:52:17.000000000 +0800
+++ linux-2.6.33_perfkvm/include/linux/perf_event.h 2010-03-02 12:26:15.050947780 +0800
@@ -125,8 +125,9 @@ enum perf_event_sample_format {
PERF_SAMPLE_PERIOD = 1U << 8,
PERF_SAMPLE_STREAM_ID = 1U << 9,
PERF_SAMPLE_RAW = 1U << 10,
+ PERF_SAMPLE_KVM = 1U << 11,
- PERF_SAMPLE_MAX = 1U << 11, /* non-ABI */
+ PERF_SAMPLE_MAX = 1U << 12, /* non-ABI */
};
/*
@@ -798,7 +799,7 @@ extern void perf_output_sample(struct pe
struct perf_event_header *header,
struct perf_sample_data *data,
struct perf_event *event);
-extern void perf_prepare_sample(struct perf_event_header *header,
+extern int perf_prepare_sample(struct perf_event_header *header,
struct perf_sample_data *data,
struct perf_event *event,
struct pt_regs *regs);
@@ -858,7 +859,6 @@ extern void perf_bp_event(struct perf_ev
#ifndef perf_misc_flags
#define perf_misc_flags(regs) (user_mode(regs) ? PERF_RECORD_MISC_USER : \
PERF_RECORD_MISC_KERNEL)
-#define perf_instruction_pointer(regs) instruction_pointer(regs)
#endif
extern int perf_output_begin(struct perf_output_handle *handle,
@@ -905,6 +905,34 @@ static inline void perf_event_enable(str
static inline void perf_event_disable(struct perf_event *event) { }
#endif
+//#if defined(CONFIG_PERF_EVENTS && CONFIG_PERF_HAS_VIRT_IP)
+#if defined(CONFIG_PERF_EVENTS)
+struct virt_ip_info {
+ int user_mode;
+ u64 ip;
+};
+
+DECLARE_PER_CPU(struct virt_ip_info, perf_virt_ip);
+extern void perf_save_virt_ip(int user_mode, u64 ip);
+extern void perf_reset_virt_ip(void);
+extern int perf_get_virt_user_mode(void);
+static inline u64 perf_instruction_pointer(struct perf_event *event, struct pt_regs *regs)
+{
+ u64 ip;
+ if (event->attr.sample_type & PERF_SAMPLE_KVM)
+ ip = percpu_read(perf_virt_ip.ip);
+ else
+ ip = instruction_pointer(regs);
+ return ip;
+}
+#else
+static inline void perf_save_virt_ip(int user_mode, u64 ip) { }
+static inline void perf_reset_virt_ip(void) { }
+static inline int perf_get_virt_user_mode(void) { return -1; }
+#define perf_instruction_pointer(event, regs) instruction_pointer(regs))
+#endif
+
+
#define perf_output_put(handle, x) \
perf_output_copy((handle), &(x), sizeof(x))
--- linux-2.6.33/kernel/perf_event.c 2010-02-25 02:52:17.000000000 +0800
+++ linux-2.6.33_perfkvm/kernel/perf_event.c 2010-03-02 12:30:41.236003180 +0800
@@ -3077,7 +3077,38 @@ void perf_output_sample(struct perf_outp
}
}
-void perf_prepare_sample(struct perf_event_header *header,
+//#ifdef CONFIG_PERF_VIRT_IP
+DEFINE_PER_CPU(struct virt_ip_info, perf_virt_ip) = {0,0};
+EXPORT_PER_CPU_SYMBOL(perf_virt_ip);
+
+void perf_save_virt_ip(int user_mode, u64 ip)
+{
+ if (!atomic_read(&nr_events))
+ return;
+ percpu_write(perf_virt_ip.user_mode, ip);
+ percpu_write(perf_virt_ip.ip, ip);
+}
+EXPORT_SYMBOL_GPL(perf_save_virt_ip);
+
+void perf_reset_virt_ip(void)
+{
+ if (!percpu_read(perf_virt_ip.ip))
+ return;
+ percpu_write(perf_virt_ip.user_mode, 0);
+ percpu_write(perf_virt_ip.ip, 0);
+}
+EXPORT_SYMBOL_GPL(perf_reset_virt_ip);
+
+int perf_get_virt_user_mode(void)
+{
+ if (!percpu_read(perf_virt_ip.ip))
+ return -1;
+ return percpu_read(perf_virt_ip.user_mode);
+}
+
+//#endif
+
+int perf_prepare_sample(struct perf_event_header *header,
struct perf_sample_data *data,
struct perf_event *event,
struct pt_regs *regs)
@@ -3090,10 +3121,15 @@ void perf_prepare_sample(struct perf_eve
header->size = sizeof(*header);
header->misc = 0;
- header->misc |= perf_misc_flags(regs);
+ if (event->attr.sample_type & PERF_SAMPLE_KVM)
+ header->misc |= percpu_read(perf_virt_ip.user_mode)?PERF_RECORD_MISC_USER:PERF_RECORD_MISC_KERNEL;
+ else
+ header->misc |= perf_misc_flags(regs);
if (sample_type & PERF_SAMPLE_IP) {
- data->ip = perf_instruction_pointer(regs);
+ data->ip = perf_instruction_pointer(event, regs);
+ if (!data->ip)
+ return -1;
header->size += sizeof(data->ip);
}
@@ -3162,6 +3198,8 @@ void perf_prepare_sample(struct perf_eve
WARN_ON_ONCE(size & (sizeof(u64)-1));
header->size += size;
}
+
+ return 0;
}
static void perf_event_output(struct perf_event *event, int nmi,
@@ -3170,8 +3208,11 @@ static void perf_event_output(struct per
{
struct perf_output_handle handle;
struct perf_event_header header;
+ int ret;
- perf_prepare_sample(&header, data, event, regs);
+ ret = perf_prepare_sample(&header, data, event, regs);
+ if (ret)
+ return;
if (perf_output_begin(&handle, event, header.size, nmi, 1))
return;
--- linux-2.6.33/tools/perf/builtin-record.c 2010-02-25 02:52:17.000000000 +0800
+++ linux-2.6.33_perfkvm/tools/perf/builtin-record.c 2010-03-02 13:19:53.564376291 +0800
@@ -251,6 +251,8 @@ static void create_counter(int counter,
PERF_FORMAT_ID;
attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
+ if (sample_kvm)
+ attr->sample_type |= PERF_SAMPLE_KVM;
if (freq) {
attr->sample_type |= PERF_SAMPLE_PERIOD;
--- linux-2.6.33/tools/perf/builtin-top.c 2010-02-25 02:52:17.000000000 +0800
+++ linux-2.6.33_perfkvm/tools/perf/builtin-top.c 2010-03-01 16:35:41.972067501 +0800
@@ -1091,6 +1091,8 @@ static void start_counter(int i, int cou
attr = attrs + counter;
attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
+ if (sample_kvm)
+ attr->sample_type |= PERF_SAMPLE_KVM;
if (freq) {
attr->sample_type |= PERF_SAMPLE_PERIOD;
--- linux-2.6.33/tools/perf/perf.c 2010-02-25 02:52:17.000000000 +0800
+++ linux-2.6.33_perfkvm/tools/perf/perf.c 2010-03-02 09:57:03.164001069 +0800
@@ -28,6 +28,8 @@ struct pager_config {
int val;
};
+int sample_kvm = 0;
+
static char debugfs_mntpt[MAXPATHLEN];
static int pager_command_config(const char *var, const char *value, void *data)
@@ -320,6 +322,13 @@ static void handle_internal_command(int
argv[0] = cmd = "help";
}
+ if (argc > 1 && !strcmp(argv[0], "kvm")) {
+ sample_kvm = 1;
+ argv++;
+ argc--;
+ cmd = argv[0];
+ }
+
for (i = 0; i < ARRAY_SIZE(commands); i++) {
struct cmd_struct *p = commands+i;
if (strcmp(p->cmd, cmd))
--- linux-2.6.33/tools/perf/perf.h 2010-02-25 02:52:17.000000000 +0800
+++ linux-2.6.33_perfkvm/tools/perf/perf.h 2010-03-01 16:12:42.470082418 +0800
@@ -131,4 +131,6 @@ struct ip_callchain {
u64 ips[0];
};
+extern int sample_kvm;
+
#endif
next prev parent reply other threads:[~2010-03-02 7:06 UTC|newest]
Thread overview: 99+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-25 15:04 KVM PMU virtualization Jes Sorensen
2010-02-25 15:44 ` Jan Kiszka
2010-02-25 16:26 ` Ingo Molnar
2010-02-26 2:52 ` Zhang, Yanmin
2010-02-26 8:45 ` Ingo Molnar
2010-02-26 11:03 ` Jes Sorensen
2010-02-25 17:34 ` Joerg Roedel
2010-02-26 2:55 ` Zhang, Yanmin
2010-02-26 8:51 ` Joerg Roedel
2010-02-26 9:17 ` Ingo Molnar
2010-02-26 10:42 ` Joerg Roedel
2010-02-26 10:56 ` Ingo Molnar
2010-03-02 7:09 ` Zhang, Yanmin [this message]
2010-03-02 9:36 ` Ingo Molnar
2010-03-03 3:32 ` Zhang, Yanmin
2010-03-03 9:27 ` Zhang, Yanmin
2010-03-03 10:13 ` Peter Zijlstra
2010-03-04 0:52 ` Zhang, Yanmin
2010-03-03 10:15 ` Peter Zijlstra
2010-03-04 1:00 ` Zhang, Yanmin
2010-03-10 9:29 ` Zhang, Yanmin
2010-03-02 9:57 ` Peter Zijlstra
2010-02-26 8:42 ` Ingo Molnar
2010-02-26 9:46 ` Avi Kivity
2010-02-26 10:39 ` Joerg Roedel
2010-02-26 10:46 ` Ingo Molnar
2010-02-26 10:51 ` Avi Kivity
2010-02-26 11:06 ` Joerg Roedel
2010-02-26 11:18 ` Jes Sorensen
2010-02-26 11:24 ` Ingo Molnar
2010-02-26 11:25 ` Jes Sorensen
2010-02-26 11:20 ` Ingo Molnar
2010-02-26 10:44 ` Ingo Molnar
2010-02-26 11:16 ` Avi Kivity
2010-02-26 11:26 ` Ingo Molnar
2010-02-26 11:47 ` Avi Kivity
2010-02-26 11:23 ` Jes Sorensen
2010-02-26 11:42 ` Ingo Molnar
2010-02-26 11:51 ` Avi Kivity
2010-02-26 12:07 ` Ingo Molnar
2010-02-26 12:20 ` Avi Kivity
2010-02-26 12:38 ` Ingo Molnar
2010-02-26 13:04 ` Avi Kivity
2010-02-26 13:13 ` Jes Sorensen
2010-02-26 13:27 ` Ingo Molnar
2010-02-26 13:33 ` Avi Kivity
2010-02-26 14:07 ` Jes Sorensen
2010-02-26 14:11 ` Avi Kivity
2010-02-26 13:18 ` Ingo Molnar
2010-02-26 13:34 ` Jes Sorensen
2010-02-26 12:56 ` Jes Sorensen
2010-02-26 13:31 ` Ingo Molnar
2010-02-26 13:37 ` Jes Sorensen
2010-02-26 13:55 ` Avi Kivity
2010-02-26 14:27 ` Peter Zijlstra
2010-02-26 14:54 ` Avi Kivity
2010-02-26 15:08 ` Peter Zijlstra
2010-02-26 15:11 ` Avi Kivity
2010-02-26 15:18 ` Peter Zijlstra
2010-02-26 15:55 ` Peter Zijlstra
2010-02-26 16:06 ` Avi Kivity
2010-03-01 19:03 ` Zachary Amsden
2010-03-01 18:54 ` Zachary Amsden
2010-02-26 13:40 ` Avi Kivity
2010-02-26 14:01 ` Ingo Molnar
2010-02-26 14:22 ` Avi Kivity
2010-02-26 14:37 ` Ingo Molnar
2010-02-26 16:03 ` Avi Kivity
2010-02-26 16:07 ` Avi Kivity
2010-02-26 13:28 ` Peter Zijlstra
2010-02-26 13:44 ` Avi Kivity
2010-02-26 13:51 ` Jes Sorensen
2010-02-26 14:42 ` Peter Zijlstra
2010-03-08 18:14 ` Avi Kivity
2010-02-26 12:49 ` Jes Sorensen
2010-02-26 13:06 ` Ingo Molnar
2010-02-26 13:30 ` Avi Kivity
2010-02-26 13:32 ` Jes Sorensen
2010-02-26 13:44 ` Ingo Molnar
2010-02-26 13:53 ` Avi Kivity
2010-02-26 14:12 ` Ingo Molnar
2010-02-26 14:53 ` Avi Kivity
2010-02-26 15:14 ` Peter Zijlstra
2010-02-28 16:34 ` Joerg Roedel
2010-02-28 16:31 ` Joerg Roedel
2010-02-28 16:11 ` Joerg Roedel
2010-03-01 8:39 ` Ingo Molnar
2010-03-01 8:58 ` Joerg Roedel
2010-03-01 9:04 ` Ingo Molnar
2010-03-01 8:44 ` Ingo Molnar
2010-03-01 11:11 ` Joerg Roedel
2010-03-01 17:17 ` Peter Zijlstra
2010-03-01 18:36 ` Joerg Roedel
2010-03-08 10:15 ` Avi Kivity
2010-02-26 14:49 ` Peter Zijlstra
2010-02-26 14:50 ` Peter Zijlstra
2010-02-26 13:31 ` Jes Sorensen
2010-03-01 17:22 ` Zachary Amsden
2010-02-26 11:01 ` Jes Sorensen
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=1267513746.1726.104.camel@localhost \
--to=yanmin_zhang@linux.intel.com \
--cc=Jes.Sorensen@redhat.com \
--cc=avi@redhat.com \
--cc=gleb@redhat.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=ming.m.lin@intel.com \
--cc=mingo@elte.hu \
--cc=peterz@infradead.org \
--cc=zamsden@redhat.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.