Bug 26661 - 32-Bit SMP-VM hängt auf 64-Bit Host
32-Bit SMP-VM hängt auf 64-Bit Host
Status: CLOSED FIXED
Product: UCS
Classification: Unclassified
Component: Virtualization - KVM
UCS 3.0
amd64 Linux
: P4 normal (vote)
: UCS 3.0-1-errata
Assigned To: Philipp Hahn
Janek Walkenhorst
:
Depends on: 26836 26889
Blocks: 26839
  Show dependency treegraph
 
Reported: 2012-03-29 15:21 CEST by Philipp Hahn
Modified: 2012-11-09 16:22 CET (History)
3 users (show)

See Also:
What kind of report is it?: ---
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional): Troubleshooting
Max CVSS v3 score:


Attachments
686-bigmem VM deadlock (6.79 KB, patch)
2012-04-19 08:57 CEST, Philipp Hahn
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Philipp Hahn univentionstaff 2012-03-29 15:21:02 CEST
Ticket #2012030921001381 (Kunde 13660)
Ticket #2012010621003682 (Intern)

Sowohl intern alsauch bei einem Kunden tritt das Problem auf, da eine 32-Bit-VM mit mehreren CPUs auf einem 64-Bit Hostsystem nach einiger Zeit stehen bleibt und nicht mehr auf Pings reagiert.
Das ganze wurde per gdb <https://hutten.knut.univention.de/mediawiki/index.php/Philipp_memo/debug#gdb_.2B_Linux-Kernel> soweit analysiert, daß es vermutlich zu einem Problem mit dem IPI <http://de.wikipedia.org/wiki/Inter_Processor_Interrupt> kommt, der nicht alle CPUs erreicht: Ein Prozesser wartet in flush_tlb_others_ipi() aus das ACK noch mindestens einer anderen CPUs, während alle anderer CPUs darauf warten, daß der pgd_lock wieder freigegeben wird.

Das Reduzieren der Gast-CPU-Anzahl von 4 auf 2 hat nur die Wahrscheinlichkeit einer Verklemmung reduziert, aber nicht beseitigt.

Ein Update des Gast-Kernels auf 3.x hat nicht geholfen.

Auf der KVM-ML wurde bereits nachgefragt, dort erfolgte aber bisher keine Reaktion.

Weiteres vorgeschlagenes Vorgehen:
1. Neuere Version von qemu-kvm bauen und testen, ob es damit immer noch auftritt.
2. Neueren Host-Kernel bauen und testen, ob es damit immer noch auftritt.
3. Mit diesen Ergebnisse nochmal die KVM-ML befragen.
Comment 1 Philipp Hahn univentionstaff 2012-04-16 12:06:47 CEST
(In reply to comment #0)
> Ein Update des Gast-Kernels auf 3.x hat nicht geholfen.
Mit dem Kernel linux-3.2 konnte da Problem bisher nicht beobachtet werden, auch nicht mit einem 3.3+git, von daher sollte das noch mal gerüft werden.

> Weiteres vorgeschlagenes Vorgehen:
> 1. Neuere Version von qemu-kvm bauen und testen, ob es damit immer noch
> auftritt.
Ein Upgrade auf qemu-1.0 hat alleine nicht geholfen.

> 2. Neueren Host-Kernel bauen und testen, ob es damit immer noch auftritt.
Ein Upgrade des Hosts auf linux-3.2 hat alleine nichts geholfen.

> 3. Mit diesen Ergebnisse nochmal die KVM-ML befragen.
Bisher keine Reaktion.
Comment 2 Philipp Hahn univentionstaff 2012-04-17 10:36:17 CEST
Host-Kernel 3.3.0 hilft nicht.
qemu-kvm_1.0.50 hilft nicht.
Gast-Kernel 3.2 half.
Bug tritt sowohl auf Intel- als auch bei AMD-CPUs auf.

./trace-cmd record -e kvm:kvm_apic_ipi -e kvm:kvm_apic_accept_irq -b 20000
./trace-cmd report
 16172 [001] 20741.007969: kvm_apic_ipi:         dst 2 vec 242 (Fixed|logical|de-assert|edge|dst)
 16172 [001] 20741.007970: kvm_apic_accept_irq:  apicid 1 vec 242 (Fixed|edge)

(gdb) print f->flush_cpumask
$4 = {2}
OK: Stimmt mit dst=2 überein.

(gdb) info threads 
* 3 Thread 3 (CPU#2 [running])  0xc1024a3e in flush_tlb_others_ipi (cpumask=0xf613fb98, mm=<value optimized out>, va=4294967295)
    at /mnt/omar/sde/buildsystem2/temp/tmp.VYxvIgEXXg/3.0-0-0/linux-2.6.32/linux-2.6.32-2.6.32/debian/build/source_i386_none/arch/x86/mm/tlb.c:195
OK: Thread 3 = CPU 2 = SMP-ID 2 = INVALIDATE_TLB_VECTOR_START+2 = vec 242

Der IPI wurde scheinbar auch an CPU 2 durchgereicht: apicid=1

Auffällig ist noch, das der Fehler immer zweimal hintereinander auftritt: Nach dem ersten "set variable f->flush_cpumask=0" und anschließendem "continue" muß die VM nochmal per Ctrl-C unterbrochen werden und das ganze wiederholt werden. Erst dann läuft die VM wieder ein ganzes Stück weiter,

 [001] 17922.264040: kvm_apic_ipi:         dst 1 vec 241 (Fixed|logical|de-assert|edge|dst)
 [001] 17922.264043: kvm_apic_accept_irq:  apicid 0 vec 241 (Fixed|edge) (coalesced)

Das "coalesced" könnte ein Zeichen dafür sein, daß hier ein IPI verloren geht bzw. erst mit dem 2. IPI zusammen die CPU erreicht.


Bei einem anderen Kunden treten auch bei einem i386 UCS-2.4-Master gelegentliche Aussetzer unter VMWare-ESX auf: Die 4-Kern-VM wird als 75% busy angezeigt (3*Spin-Lock?). Mit Kernel ucs37 was es noch okay, seit ucs44 schlägt es fehl.
Wenn das der selbe Bug ist, würde das für einen Fehler im Gast-Kernel sprechen.
Comment 3 Philipp Hahn univentionstaff 2012-04-17 13:06:41 CEST
Der diff zwischen den Kerneln aus ucs2.4-2 und sec2.4-4 hat folgenden Patch zu Tage gefördert:

<http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;h=831d52bc153971b70e64eccfbed2b232394f22f8>
x86, mm: avoid possible bogus tlb entries by clearing prev mm_cpumask after switching mm

Das würde zumindest passen. Eine Suche nach der commit-Id hat dann folgenden Problembericht im Zusammenhang mit Xen gefunden:

xen mmu: fix a race window causing leave_mm BUG()
<http://web.archiveorange.com/archive/v/tXSRNGY4xsEhAzCRnIpi>
<http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;h=7899891c7d161752f29abcc9bc0a9c6c3a3af26c>

Da wurde zumindest ein Problem in Xen korrigiert; ggf. ist was ähnliches auch für kvm relevant?

Den oberen Patch zurückzunehmen hilft laut Aussage eines Testers nicht, weil die eigentliche Race-Condition dann immer noch vorhanden ist, nur nicht mehr so häufig auftritt.
Comment 4 Philipp Hahn univentionstaff 2012-04-19 08:57:31 CEST
Created attachment 4334 [details]
686-bigmem VM deadlock

Mit ucs37 (entspricht 2.6.32.28) tritt das Problem nicht auf, mit ucs44 (entspricht 2.6.32.41) dagegen wohl.

Bei alle Kunden, bei denen das Problem aufgetreten ist, und auch bei uns wird der bigmem-Kernel verwendet. Vermutet wurde, das dort der xen/pvops.patch aktiviert ist, aber das ist nur bei dem xen-686-Kernel der Fall (das ist auch ein bigmem-Kernel, aber eben mit den Xen-Patches für den Betrieb als dom0-Kernel)

Dort wird die Implementierung von arch/x86/mm/tlb.c geändert: Statt originalen Funktion flush_tlb_all() wird dort indirekt auch flush_tlb_others() verwendet.

In der Funktion werden die beiden Zustände TLBSTATE_OK und TLBSTATE_LAZY betrachtet, nicht aber der 3. Zustand '0', bei dem dann das leave_mm() unterbleibt. (Der Zustand tritt nach Code-Studium nur Initial und bei CPU-Hotplug auf) Dadurch wird die CPU weiterhin als eine CPU geführt, in der die MM aktiv ist. Beim nächsten flush_tlb_others() wird dann vermutlich von der CPU eine Antwort auf das flush_tlb_others() erwartet, was diese dann nicht sendet.

--- debian/patches/features/all/xen/pvops.patch
+++ debian/patches/features/all/xen/pvops.patch
@@ -3117,1 +3117,1 @@
-+		if (tlbstate == TLBSTATE_LAZY)
++		if (tlbstate != TLBSTATE_OK)

Das war es aber nicht.


Aufgefallen ist folgender Patch: <http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;h=4981d01eada5354d81c8929d5b2836829ba3df7b>: x86: Flush TLB if PGD entry is changed in i386 PAE mode

Wird der zurückgenommen, so läuft der Build-Vorgang wieder.
Allerdings korrigiert der Patch eigentlich ein Problem bei Multi-Threaded-Programmen, die Memory-Mapped-Files benutzen, von daher ist ein blindes Zurücknehmen des Patches nicht die beste Lösung.


Im git-Repository finde man aber noch einen weiteren Patch, der in 2.6.32.44 noch fehlt: <http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;h=a79e53d85683c6dd9f99c90511028adc2043031f>: x86/mm: Fix pgd_lock deadlock

Das passt zumindest thematisch sehr, muß aber noch mal getestet werden. Der Patch wurde für den 2.6.37-longterm zurück portiert und für SLES11-SP1 nach 2.6.32: <http://kernel.opensuse.org/cgit/kernel-source/commit/?id=ac27c01aa880c65d17043ab87249c613ac4c3635>

Im Debian-Kernel ist der auch schon enthalten (features/all/xen/x86-mm-Fix-pgd_lock-deadlock.patch), allerdings nur für das Xen-Featureset aktiviert); er passt nicht 1:1 auf einen nicht-Xen-Kernel, aber die Änderungen leicht zu portieren. (Nach Absprache mit Moritz gibt es dafür den neuen Debian-Bug <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=669335>.)

Mit dem gepatchten Kernel war mein Torture-Test heute Nacht mit einem schnell selbst gebauten Kernel erfolgreich: Nach 8 Stunden noch kein Hänger mit 4 parallelen Builds von OpenOffice, 2×Samba, Kernel)

Insgesamt macht die Patchserie auch Sinn: Der "Flush TLB if PGD entry is changed in i386 PAE mode"-Patch führt dazu, das es aus Korrekthitsgründen zu mehr TLB-Flushes kommt, was dann zu den beobachteten Deadlock führt, was dann durch den "Fix pgd_lock deadlock"-Patch behoben wird.
Comment 5 Philipp Hahn univentionstaff 2012-04-19 12:07:45 CEST
Patch wurde eingespielt und für i386 gebaut; amd64 baut wegen Bug #21260
vermutlich noch ein paar Stunden, aber das ist für die QA weniger relevant.

svn10305, linux-2.6.32_2.6.32-38~ucs1.61.201204182319 in ucs_3.0-0-errata3.0-1
svn10307, univention-kernel-image-2.6.32_5.0.0-1.57.201204191104

Wegen Bug #26836 in repo-ng wird es zwei Advisories geben: 
2012-04-19-linux-2.6.32.yaml, svn12862
2012-04-19-univention-kernel-image-2.6.32.yaml, svn12864


Für die QA:
Je mehr VCPUs, um so einfacher lässt sich das Problem provozieren.
Mehrere parallele Builds (o3, s4, lk) starten, bei 6 CPUs stand die VM innerhalb von Sekunden—Minuten.
Ein "watch cat /proc/interrupts" sollte viele "TLB shootdowns" zeigen, denn die sind für den Fehler verantwortlich.
Comment 6 Janek Walkenhorst univentionstaff 2012-04-20 17:34:32 CEST
Bug lässt sich mit i386 nachstellen: OK
Nach dem Update lässt er sich nicht mehr nachstellen: OK
Advisories: OK.
Kernel funktioniert auch mit amd64: OK
Comment 7 Philipp Hahn univentionstaff 2012-04-23 11:18:26 CEST
<file:/var/univention/buildsystem2/errata/staging/errata57.txt>
<file:/var/univention/buildsystem2/errata/staging/errata57.txt.asc>
<file:/var/univention/buildsystem2/errata/staging/errata58.txt>
<file:/var/univention/buildsystem2/errata/staging/errata58.txt.asc>
<http://univention-repository.knut.univention.de/download/errata/>
<http://univention-repository.knut.univention.de/download/errata/errata57.html>
<http://univention-repository.knut.univention.de/download/errata/errata58.html>
Comment 9 Philipp Hahn univentionstaff 2012-04-24 09:46:50 CEST
Der Kernel wurde nochmal basierend auf der Version aus UCS-3.0-1 neu gebaut:

# apt-cache policy univention-kernel-image-2.6.32 linux-image-2.6.32-ucs60-686
univention-kernel-image-2.6.32:
  Installiert: 5.0.1-1.56.201202271212
  Kandidat:    5.0.1-1.56.201202271212
  Versionstabelle:
 *** 5.0.1-1.56.201202271212 0
        500 http://apt.knut.univention.de/3.0/maintained/ 3.0-1/i386/ Packages
        100 /var/lib/dpkg/status
     5.0.0-1.51.201112050913 0
        500 http://apt.knut.univention.de/3.0/maintained/ 3.0-0/i386/ Packages
linux-image-2.6.32-ucs60-686:
  Installiert: 2.6.32-41~ucs1.60.201202231541
  Kandidat:    2.6.32-41~ucs1.60.201202231541
  Versionstabelle:
 *** 2.6.32-41~ucs1.60.201202231541 0
        500 http://apt.knut.univention.de/3.0/maintained/ 3.0-1/i386/ Packages
        100 /var/lib/dpkg/status

svn10320, svn10320, linux-2.6.32_2.6.32-41~ucs1.62.201204231104
svn10324, univention-kernel-image-2.6.32_5.0.1-1.59.201204240852
svn12893, svn12894: 2012-04-{19→24}-{linux,univention-kernel-image}-2.6.32.yaml
Comment 10 Philipp Hahn univentionstaff 2012-04-24 11:04:35 CEST
svn10326, svn10327, univention-kernel-image-2.6.32_5.0.1-1.60.201204241058
svn12898, 2012-04-24-univention-kernel-image-2.6.32.yaml
Comment 11 Janek Walkenhorst univentionstaff 2012-04-24 14:22:38 CEST
Advisories: OK
Version: OK
Installation und Abhängikeiten: OK