* IRQ affinity on Linux guest
@ 2015-08-20 14:16 Mihai Neagu
2015-08-20 23:20 ` Radim Krčmář
0 siblings, 1 reply; 4+ messages in thread
From: Mihai Neagu @ 2015-08-20 14:16 UTC (permalink / raw)
To: kvm; +Cc: adrian.papp, vicentiu.neagoe
Hello,
I'm trying to assign some IRQ affinities to core 0 by setting
smp_affinity to 1.
This is on a dual-core embedded Linux virtual machine ran with KVM.
However, ISRs continue to run on both cores.
The same technique works well with QEMU with full software emulation.
Here is the output of the following:
host> uname -a
Linux rtcon2 3.19.0-22-generic #22~14.04.1-Ubuntu SMP Wed Jun 17
10:03:13 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
guest> uname -a
Linux NI-cRIO-Linux-525400123456 3.14.40-rt37-nilrt #1 SMP PREEMPT RT
Thu Aug 6 20:35:41 EEST 2015 x86_64 GNU/Linux
host> kvm --version
QEMU emulator version 2.0.0 (Debian 2.0.0+dfsg-2ubuntu1.15), Copyright
(c) 2003-2008 Fabrice Bellard
Here is how IRQ affinity is configured on guest at startup, in an init.d
script:
echo 1 > /proc/irq/default_smp_affinity
for x in /proc/irq/*/smp_affinity;
do
echo 1 > $x
done 2> /dev/null
The command line for starting the hardware accelerated VM:
kvm -kernel bzImage -hda rootfs.ext2 -append "root=/dev/sda console=ttyS0 \
rw" -nographic -cpu qemu64 -snapshot -smp 2 -m 2048
... which actually runs this:
qemu-system-x86-64 -enable-kvm -kernel bzImage -hda rootfs.ext2 -append \
"root=/dev/sda console=ttyS0 rw" -nographic -cpu qemu64 -snapshot -smp 2 \
-m 2048
On the hardware accelerated guest, 'cat /proc/interrupts' shows:
CPU0 CPU1
0: 26 0 IO-APIC-edge timer
1: 7 4 IO-APIC-edge i8042
4: 1137 523 IO-APIC-edge serial
8: 0 1 IO-APIC-edge rtc0
9: 0 0 IO-APIC-fasteoi acpi
11: 4971 4 IO-APIC-fasteoi eth0
12: 66 64 IO-APIC-edge i8042
14: 1958 714 IO-APIC-edge ata_piix
15: 4512 63 IO-APIC-edge ata_piix
...
Interrupts are serviced on both cores, even though affinity is set to 1.
The command line for starting full software emulation VM is:
qemu-system-x86_64 -kernel bzImage -hda rootfs.ext2 -append "root=/dev/sda \
console=ttyS0 rw" -nographic -cpu qemu64 -snapshot -smp 2 -m 2048
On the full software emulation guest, 'cat /proc/interrupts' shows:
CPU0 CPU1
0: 36 0 IO-APIC-edge timer
1: 10 0 IO-APIC-edge i8042
4: 1775 0 IO-APIC-edge serial
8: 1 0 IO-APIC-edge rtc0
9: 0 0 IO-APIC-fasteoi acpi
11: 345 0 IO-APIC-fasteoi eth0
12: 125 0 IO-APIC-edge i8042
14: 1720 0 IO-APIC-edge ata_piix
15: 481 0 IO-APIC-edge ata_piix
...
Interrupts are serviced only on CPU0, therefore setting IRQ affinity worked.
Do you have any idea why KVM doesn't respect IRQ affinity on the guest?
What can I do to get it working with IRQ affinity set to 1?
Thanks,
Mihai
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: IRQ affinity on Linux guest
2015-08-20 14:16 IRQ affinity on Linux guest Mihai Neagu
@ 2015-08-20 23:20 ` Radim Krčmář
2015-08-21 12:33 ` Mihai Neagu
0 siblings, 1 reply; 4+ messages in thread
From: Radim Krčmář @ 2015-08-20 23:20 UTC (permalink / raw)
To: Mihai Neagu; +Cc: kvm, adrian.papp, vicentiu.neagoe
2015-08-20 17:16+0300, Mihai Neagu:
> Here is how IRQ affinity is configured on guest at startup, in an init.d
> script:
>
> echo 1 > /proc/irq/default_smp_affinity
> for x in /proc/irq/*/smp_affinity;
> do
> echo 1 > $x
> done 2> /dev/null
>
> The command line for starting the hardware accelerated VM:
> qemu-system-x86-64 -enable-kvm -kernel bzImage -hda rootfs.ext2 -append \
> "root=/dev/sda console=ttyS0 rw" -nographic -cpu qemu64 -snapshot -smp 2 \
> -m 2048
>
> On the hardware accelerated guest, 'cat /proc/interrupts' shows:
> CPU0 CPU1
> 0: 26 0 IO-APIC-edge timer
> 1: 7 4 IO-APIC-edge i8042
> 4: 1137 523 IO-APIC-edge serial
> 8: 0 1 IO-APIC-edge rtc0
> 9: 0 0 IO-APIC-fasteoi acpi
> 11: 4971 4 IO-APIC-fasteoi eth0
> 12: 66 64 IO-APIC-edge i8042
> 14: 1958 714 IO-APIC-edge ata_piix
> 15: 4512 63 IO-APIC-edge ata_piix
> ...
> Interrupts are serviced on both cores, even though affinity is set to 1.
KVM's APIC balances interrupts -- until you set the affinity (probably
near the end of boot process), both CPUs are going to receive roughly
the same amount but after directing subsequent interrupts to CPU0, CPU1
shouldn't receive more.
Please verify that CPU0 is not receiving all interrupts by doing a
difference between two `cat /proc/interrupts` after the affinity was
set. (CPU0 has higher numbers in your excerpt, which makes me suspect
that it works as expected.)
Thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: IRQ affinity on Linux guest
2015-08-20 23:20 ` Radim Krčmář
@ 2015-08-21 12:33 ` Mihai Neagu
2015-08-21 14:46 ` Paolo Bonzini
0 siblings, 1 reply; 4+ messages in thread
From: Mihai Neagu @ 2015-08-21 12:33 UTC (permalink / raw)
To: Radim Krčmář; +Cc: kvm, adrian.papp, vicentiu.neagoe
Radim,
Thanks for your answer. Indeed setting IRQ affinity to a specific core
seems to be respected.
However, on software emulation and on the real machine, while IRQ
affinity defaults to 3, all interrupts go on CPU0, while on KVM they go
on CPU1.
I wonder why KVM would act differently than both the real machine and
the software emulation in this particular aspect.
Is there a machine or processor that I can specify at KVM command line
to make it behave like the real x86_64 processor which defaults
interrupts to CPU0?
Thanks,
Mihai
On 08/21/2015 02:20 AM, Radim Krčmář wrote:
> 2015-08-20 17:16+0300, Mihai Neagu:
>> Here is how IRQ affinity is configured on guest at startup, in an init.d
>> script:
>>
>> echo 1 > /proc/irq/default_smp_affinity
>> for x in /proc/irq/*/smp_affinity;
>> do
>> echo 1 > $x
>> done 2> /dev/null
>>
>> The command line for starting the hardware accelerated VM:
>> qemu-system-x86-64 -enable-kvm -kernel bzImage -hda rootfs.ext2 -append \
>> "root=/dev/sda console=ttyS0 rw" -nographic -cpu qemu64 -snapshot -smp 2 \
>> -m 2048
>>
>> On the hardware accelerated guest, 'cat /proc/interrupts' shows:
>> CPU0 CPU1
>> 0: 26 0 IO-APIC-edge timer
>> 1: 7 4 IO-APIC-edge i8042
>> 4: 1137 523 IO-APIC-edge serial
>> 8: 0 1 IO-APIC-edge rtc0
>> 9: 0 0 IO-APIC-fasteoi acpi
>> 11: 4971 4 IO-APIC-fasteoi eth0
>> 12: 66 64 IO-APIC-edge i8042
>> 14: 1958 714 IO-APIC-edge ata_piix
>> 15: 4512 63 IO-APIC-edge ata_piix
>> ...
>> Interrupts are serviced on both cores, even though affinity is set to 1.
> KVM's APIC balances interrupts -- until you set the affinity (probably
> near the end of boot process), both CPUs are going to receive roughly
> the same amount but after directing subsequent interrupts to CPU0, CPU1
> shouldn't receive more.
>
> Please verify that CPU0 is not receiving all interrupts by doing a
> difference between two `cat /proc/interrupts` after the affinity was
> set. (CPU0 has higher numbers in your excerpt, which makes me suspect
> that it works as expected.)
>
> Thanks.
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: IRQ affinity on Linux guest
2015-08-21 12:33 ` Mihai Neagu
@ 2015-08-21 14:46 ` Paolo Bonzini
0 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2015-08-21 14:46 UTC (permalink / raw)
To: Mihai Neagu, Radim Krčmář
Cc: kvm, adrian.papp, vicentiu.neagoe
On 21/08/2015 05:33, Mihai Neagu wrote:
> Radim,
>
> Thanks for your answer. Indeed setting IRQ affinity to a specific core
> seems to be respected.
>
> However, on software emulation and on the real machine, while IRQ
> affinity defaults to 3, all interrupts go on CPU0, while on KVM they go
> on CPU1.
Are you sure that KVM doesn't do some kind of round robin?
Also, it's probably not _all_ interrupts but most of them. For example
my laptop has:
smp_affinity
cpu0 cpu1 cpu2 cpu3 ||||
1: 32824 1764 151 130 IO-APIC-edge i8042 0123
12: 1587436 203990 16666 17064 IO-APIC-edge i8042 0123
24: 63361 5160 212545 1276 PCI-MSI-edge ahci ..2.
25: 2 0 1082 10710 PCI-MSI-edge xhci_hcd ..23
29: 1867844 72169 61 57514 PCI-MSI-edge iwlwifi 0...
I added a column at the end with the SMP affinity of the interrupts.
You can see that:
* real hardware also shows traces of interrupts delivered before the
affinity was set (especially vectors 24 and 29)
* real hardware also distributes interrupts across multiple CPUs when
the affinity covers multiple processors (see vectors 1, 12 and 25)
> I wonder why KVM would act differently than both the real machine and
> the software emulation in this particular aspect.
>
> Is there a machine or processor that I can specify at KVM command line
> to make it behave like the real x86_64 processor which defaults
> interrupts to CPU0?
The behavior of interrupt arbitration is not specified in the processor
documentation and can change across processors and implementations.
Presumably it is either patented or an Intel trade secret.
Older processors were documented to pick a processor that was not
running another interrupt service routine. This can explain why
software emulation shows that all interrupts go on CPU0.
At least some newer processors are not doing it anymore, and the SDM has
some high-level explanation of their behavior and its effects:
[...] the chipset bus controller accepts messages from the I/O APIC
agents in the system and directs interrupts to the processors on the
system bus. When using the lowest priority delivery mode, the
chipset chooses a target processor to receive the interrupt out of
the set of possible targets.
In operating systems that use the lowest priority delivery mode but
do not update the TPR, the TPR information saved in the chipset will
potentially cause the interrupt to be always delivered to the same
processor from the logical set. This behavior is functionally
backward compatible with the P6 family processor but may result in
unexpected performance implications.
Other processors are doing so called "vector hashing" (i.e. pick a CPU
number based on the affinity mask and vector number, and use it most of
the time), which would also explain why the interrupts all go on CPU0.
Paolo
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-08-21 14:46 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-20 14:16 IRQ affinity on Linux guest Mihai Neagu
2015-08-20 23:20 ` Radim Krčmář
2015-08-21 12:33 ` Mihai Neagu
2015-08-21 14:46 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).