How I fixed a kernel regression using git bisect
Veröffentlicht von onny
As a happy user of the ArchLinux testing-repository, I’m sometimes “forced” to deal with bugs and regressions which do not break the whole system but definitely need some time finding and fixing them.
Beside the breaking of some userland applications like libvirt or wicd, a kernel regression, which might only affect your own system, could be really difficult to spot.
My Thinkpad T43 notebook suffered a “won’t-wakeup-from-suspend” bug since the 3.7 kernel tree and apparently this bug is still present in the latest stable upstream releases. Searching for the cause of this regression on Google isn’t really helpfull and opening tasks on your distributions bug tracker gets you in this case to the only but unpopular soloution: kernel bisection. While reading about the pros and cons of this unanalytical method, I just wanted to give it a try:
1 2 3 4 5 | git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux-git cd linux-git git bisect start git bisect good v3.6 git bisect bad v3.7-rc1 |
As you can see, I define the range in which I assume the culprit commit. Now the process of compiling and testing several kernel versions starts while narrowing down the bug. Unfortunately, I always had to compress the current revision and compile it using the offical ArchLinux PKGBUILD file on my remote server, because I couldn’t figure out how to afterwards test the kernel on my local system in a “clean” manner. Installing the bisected kernel with pacman was the more convenient way ![]()
So here’s the quite long bisection log. Note that git always stated with every step, how many commits are left to check.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | git bisect start # good: [49b8c695e331c9685e6ffdbf34872509d77c8459] Merge branch 'x86/fpu' into x86/smap git bisect good 49b8c695e331c9685e6ffdbf34872509d77c8459 # good: [49b8c695e331c9685e6ffdbf34872509d77c8459] Merge branch 'x86/fpu' into x86/smap git bisect good 49b8c695e331c9685e6ffdbf34872509d77c8459 # bad: [a20acf99f75e49271381d65db097c9763060a1e8] Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next git bisect bad a20acf99f75e49271381d65db097c9763060a1e8 # good: [06d2fe153b9b35e57221e35831a26918f462db68] Merge tag 'driver-core-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core git bisect good 06d2fe153b9b35e57221e35831a26918f462db68 # good: [3498d13b8090c0b0ef911409fbc503a7c4cca6ef] Merge tag 'tty-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty git bisect good 3498d13b8090c0b0ef911409fbc503a7c4cca6ef # bad: [61464c8357c8f6b780e4c44f5c79471799c51ca7] Merge tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc git bisect bad 61464c8357c8f6b780e4c44f5c79471799c51ca7 # good: [cc150a2861e744d8f574d571762cc7e9f928abb3] Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging git bisect good cc150a2861e744d8f574d571762cc7e9f928abb3 # good: [60e59920152c7bafc8a2eb3031a62f22c2bc9e95] Merge branch 'board' of git://github.com/hzhuang1/linux into next/cleanup git bisect good 60e59920152c7bafc8a2eb3031a62f22c2bc9e95 # bad: [797b9e5ae93270ec27a1f1ed48cd697d01b2269f] Merge branch 'for-linus' of git://git.samba.org/sfrench/cifs-2.6 git bisect bad 797b9e5ae93270ec27a1f1ed48cd697d01b2269f # good: [71953fc6e4ce5ac05b594d8e5866accf531aa969] cifs: remove kmap lock and rsize limit git bisect good 71953fc6e4ce5ac05b594d8e5866accf531aa969 # good: [c052e2b423f3eabe9f3f32e60744afa5cf26f6b9] cifs: obtain file access during backup intent lookup (resend) git bisect good c052e2b423f3eabe9f3f32e60744afa5cf26f6b9 # good: [cdeb9b014331af4282be522824e36f3aa33f0671] Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k git bisect good cdeb9b014331af4282be522824e36f3aa33f0671 # good: [a57d985e378ca69f430b85852e4187db3698a89e] Merge tag 'please-pull-ia64-for-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux git bisect good a57d985e378ca69f430b85852e4187db3698a89e # bad: [b2cc2a074de75671bbed5e2dda67a9252ef353ea] x86, smep, smap: Make the switching functions one-way git bisect bad b2cc2a074de75671bbed5e2dda67a9252ef353ea # good: [5a5a51db78ef24aa61a4cb2ae36f07f6fa37356d] x86-32: Start out eflags and cr4 clean git bisect good 5a5a51db78ef24aa61a4cb2ae36f07f6fa37356d # bad: [73201dbec64aebf6b0dca855b523f437972dc7bb] x86, suspend: On wakeup always initialize cr4 and EFER git bisect bad 73201dbec64aebf6b0dca855b523f437972dc7bb # bad: [73201dbec64aebf6b0dca855b523f437972dc7bb] x86, suspend: On wakeup always initialize cr4 and EFER git bisect bad 73201dbec64aebf6b0dca855b523f437972dc7bb # bad: [73201dbec64aebf6b0dca855b523f437972dc7bb] x86, suspend: On wakeup always initialize cr4 and EFER git bisect bad 73201dbec64aebf6b0dca855b523f437972dc7bb |
So, the last part of the session finally showed me a result:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 73201dbec64aebf6b0dca855b523f437972dc7bb is the first bad commit commit 73201dbec64aebf6b0dca855b523f437972dc7bb Author: H. Peter Anvin <hpa@linux.intel.com> Date: Wed Sep 26 15:02:34 2012 -0700 x86, suspend: On wakeup always initialize cr4 and EFER We already have a flag word to indicate the existence of MISC_ENABLES, so use the same flag word to indicate existence of cr4 and EFER, and always restore them if they exist. That way if something passes a nonzero value when the value *should* be zero, we will still initialize it. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Cc: Rafael J. Wysocki <rjw@sisk.pl> Link: http://lkml.kernel.org/r/1348529239-17943-1-git-send-email-hpa@linux.intel.com :040000 040000 bb093059ee142f1dd5bd7fe44368ba657701e451 a13e5f81b5a83f783ebeb6317599a7cd6cd4056b M arch |
I contacted the author of this commit but he was unsure about the cause of this bug and so he wanted to reproduce it on the same Thinkpad model. Meanwhile I tried to revert a part of this commit and actually fixed the bug with this patch (without knowing what it does):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | --- a/arch/x86/realmode/rm/wakeup_asm.S 2013-02-23 13:53:04.280001331 +0000 +++ b/arch/x86/realmode/rm/wakeup_asm.S 2013-02-23 13:54:14.363333655 +0000 @@ -93,8 +93,8 @@ /* Restore MISC_ENABLE before entering protected mode, in case BIOS decided to clear XD_DISABLE during S3. */ - movl pmode_behavior, %edi - btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %edi + movl pmode_behavior, %eax + btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax jnc 1f movl pmode_misc_en, %eax @@ -110,15 +110,15 @@ movl pmode_cr3, %eax movl %eax, %cr3 - btl $WAKEUP_BEHAVIOR_RESTORE_CR4, %edi - jnc 1f - movl pmode_cr4, %eax - movl %eax, %cr4 + movl pmode_cr4, %ecx + jecxz 1f + movl %ecx, %cr4 1: - btl $WAKEUP_BEHAVIOR_RESTORE_EFER, %edi - jnc 1f movl pmode_efer, %eax movl pmode_efer + 4, %edx + movl %eax, %ecx + orl %edx, %ecx + jz 1f movl $MSR_EFER, %ecx wrmsr 1: |
Now my laptop is running again with the patch applied to the latest stable kernel and suspend2ram is working again
Let’s hope that this gets fixed upstream very soon.
Dwb Flattr Extension
Veröffentlicht von onny
Wer Vimperator oder Pentadactyl unter Firefox nutzt, weiß die kompfortable Bedienung eines “VI-like”-Browsers zu schätzen. Wem mit der Zeit Firefox zu groß und langsam wurde, kann auch auf einem minimalen Browser umsteigen, der dennoch die wichtigsten Funktionen implementiert hat, dafür aber keinen “GUI”-overhead mehr besitzt. Mein Favorit ist in diesem Bereich dwb und gefühlt steigt auch immer mehr dessen Popularität. Zumindest seine Entwicklung wird weiterhin aktiv vorangetrieben und damit spürbar auch seine performance und stabilität (obwohl libwebkitgtk unter der Haube selbst in ArchTesting nicht sehr aktuell ist).
Mir fehlen dennoch einige Addons, neben YouTube/Grooveshark-Unblocker ist das noch eine Flattr-Extension:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #!javascript bind(null, function() { flattr(tabs.current.uri); }, "flattr"); function checkflattr(url){ var reqret = sendRequestSync("https://api.flattr.com/rest/v2/things/lookup?q="+url); var returnobject = JSON.parse(reqret.body); if(returnobject.message !== "not_found"){ return returnobject.id; } return false; }; function flattr(url){ var flattrid = checkflattr(url); if(flattrid){ execute("tabopen https://flattr.com/thing/"+flattrid); } else { io.notify("Flattr not available for this page!"); } }; signals.connect("loadCommitted", function(wv) { if(checkflattr(wv.uri)){ io.notify("Flattr available!"); } }); |
Problem (fürs erste) solved
Es erscheint eine kurze Meldung, dass man die Inhalte flattrn kann und mit dem Befehl :flattr ist dies auch getan. Wer Flattr nicht kennt? Klick!
Mit ein wenig Kenntnis der API lassen sich schnell noch andere, weitere Extension-Ideen umsetzen, es würde sich da einiges anbieten (auto-dl bei 1-click-hostern, autotranslate webpage …).
Fonera – Störerhaftfreier Freifunk
Veröffentlicht von onny
Mein Fonera 2100 ist leider zu alt für neuere OpenWRT-Versionen (Backfire, Attitude_Adjustment) und damit auch nicht besonders gut geeignet für Mesh-Experimente. Dennoch wollte Ich unbedingt ein Freifunk-AP in Karlsruhe aufmachen, der ein unverschlüsseltes WLAN bereitstellt (SSID: ka.freifunk.net) und allen Traffic durch einen VPN tunnelt. Der VPN-Anbieter ist in diesem Fall Ivacy.com. Das Tunneln ist insofern wichtig, da man sich aufgrund einer unschönen Gesetzeslage als Betreiber strafbar macht für das Handeln siner “Kunden”.
Nach sehr langem ausprobieren und rumbasteln ist das Setup, wenn auch nicht perfekt, einsatzbereit!
1. Fonera “jailbreaken”
Dazu gibt es schon einige Anleitungen im Netz, z.B. diese hier. Im Prinzip braucht man dazu einen USB-Serial-Adapter, wobei Ich den günstigen cp210x empfehlen kann (siehe Ebay, ~2€). Die RX/TX-Pins verbindet man mit den JTAG-Ports des Foneras. Mit z.B. minicom öffnet man die serielle Verbindung zum Gerät, nachdem man dieses gestartet hat und Konfiguriert den RedBoot-Bootloader so, dass dieser auch Images auf einer bestimmten IP-Adresse während des Startvorgangs entgegennimmt.
2. OpenWRT flashen
Zum flashen von OpenWRT auf dem Fonera benötigen wir zuerst die für dieses Gerät passenden und empfohlenen Images (Version: 8.09.2 Kamikaze) und das Programm fon-flash. Das Fonera wird direkt via. Ethernet angeschlossen und nach dem ausführen von fon-flash (das nach dem Fonera “sucht”) angeschalten:
1 2 3 4 5 | $ wget http://downloads.openwrt.org/kamikaze/8.09.2/atheros/openwrt-atheros-root.jffs2-64k $ wget http://downloads.openwrt.org/kamikaze/8.09.2/atheros/openwrt-atheros-vmlinux.lzma $ yaourt -S fon-flash $ sudo fon-flash -i eth0 -c openwrt openwrt-atheros-root.squashfs openwrt-atheros-vmlinux.lzma $ sudo ifconfig eth0 192.168.1.23 up |
3. Programme installieren
Sobald das Gerät geflasht und neugestartet ist, kann man sich mit Telnet darauf verbinden und mit dem Befehl passwd ein Passwort setzen. Als nächstes benötigt man eine Internet-Verbindung in OpenWRT um wichtige Packete zu beziehen. Am einfachsten geht das über eine eingerichtete WLAN-Verbindung mit Hilfe des Web-Interfaces.
In einer SSH-Verbindung, führt man dann folgende Befehle aus:
1 2 | opkg update opkg install pptp kmod_mppe |
Nach der Installation des Kernel-Moduls, sollte man den Router neustarten.
4. “Freifunk” konfigurieren
Die Grundidee ist: Internet wird vom WAN (Ethernet-Port des Foneras) bereitgestellt, also der LAN-Port mit z.B. dem DSL-Router verkabelt. Das WLAN-Netzwerk stellt ein eigenes, vom WAN-Port unabhängiges Subnet bereit (192.168.1.0/24) und für WLAN-Clients werden dort auch IP-Adressen verteilt. Prinzipiell wird WIFI->WAN weitergeleitet (forward), jedoch ist für WAN keine Standard-Route gesetzt (default gateway) und erst der das zusätzlich konfigurierte PPTP-Interface erstellt dann eine Route. Somit ist für Freifunk-Teilnehmer nur eine Internet-Verbindung möglich, wenn das VPN verbunden ist (yay, ein wenig dirty der workaround).
Angepasst werden müssen die Zugangsdaten für das PPTP und die statische IP am WAN-Port. OpenVPN konnte Ich leider nicht als alternative zu PPTP verwenden, da die Version bei OpenWRT Kamikaze zu alt und inkompatibel war.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package 'wireless' config 'wifi-device' 'wifi0' option 'type' 'atheros' option 'channel' 'auto' option 'disabled' '0' option 'diversity' '0' config 'wifi-iface' option 'device' 'wifi0' option 'mode' 'ap' option 'ssid' 'ka.freifunk.net' option 'network' 'freifunk' option 'encryption' 'none' option 'isolate' '1' # WLAN-Clients sehen sich gegenseitig nicht |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | package 'network' config 'interface' 'loopback' option 'ifname' 'lo' option 'proto' 'static' option 'ipaddr' '127.0.0.1' option 'netmask' '255.0.0.0' # Internet-"Input" :) config 'interface' 'wan' option 'ifname' 'eth0' option 'type' 'bridge' option 'proto' 'static' option 'ipaddr' '192.168.178.3' option 'netmask' '255.255.255.0' option 'dns' '192.168.178.1' # Wir setzen hier absichtlich keine Route, damit # Freifunk-Clients nur über den VPN das Internet # erreichen config 'interface' 'pptp' option 'proto' 'pptp' option 'username' 'user' option 'password' 'password' option 'peerdns' '0' option 'ifname' 'ppp0' option 'server' '213.229.84.200' # pptp-uk.ivacy.com option 'mtu' '1400' # Extrem wichtig, damit überhaupt Traffic durchgeht :/ # Eigenes Subnet fürs WLAN-Freifunk-Netzwerk config 'interface' 'freifunk' option 'proto' 'static' option 'ipaddr' '192.168.1.1' option 'netmask' '255.255.255.0' # Wir "verraten" dem VPN unseren Gateway, damit dieser sich verbinden kann config 'route' option 'interface' 'wan' option 'target' '213.229.84.200' option 'gateway' '192.168.178.1' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | package 'firewall' config 'defaults' option 'syn_flood' '1' option 'input' 'ACCEPT' option 'output' 'ACCEPT' option 'forward' 'REJECT' config 'zone' option 'name' 'wan' option 'network' 'wan pptp' # VPN Netzwerk hinzufügen option 'input' 'REJECT' option 'output' 'ACCEPT' option 'forward' 'REJECT' option 'masq' '1' option 'mtu_fix' '1' config 'rule' option 'src' 'wan' option 'proto' 'udp' option 'dest_port' '68' option 'target' 'ACCEPT' config 'include' option 'path' '/etc/firewall.user' config 'zone' option 'name' 'freifunk' option 'input' 'REJECT' # LuCI und SSH geblockt für Wifi-Clients option 'forward' 'REJECT' option 'output' 'ACCEPT' # Zugriff aufs lokale Netzwerk unterbinden config 'rule' option 'src' 'freifunk' option 'dest' 'wan' option 'proto' 'all' option 'dest_ip' '192.168.178.0/24' option 'target' 'DROP' # Internetzugriff fürs Freifunk-Netzwerk config 'forwarding' option 'src' 'freifunk' option 'dest' 'wan' config 'rule' option 'src' 'freifunk' option 'dest_port' '53' option 'proto' 'tcpudp' option 'target' 'ACCEPT' config 'rule' option 'src' 'freifunk' option 'src_port' '67-68' option 'dest_port' '67-68' option 'proto' 'udp' option 'target' 'ACCEPT' # SSH und Web-Zugriff von WAN aus erlauben: config 'rule' option 'src' 'wan' option 'proto' 'tcp' option 'dest_port' '22' option 'target' 'ACCEPT' config 'rule' option 'src' 'wan' option 'proto' 'tcp' option 'dest_port' '80' option 'target' 'ACCEPT' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #debug noauth logfile /dev/null noaccomp nopcomp nocrtscts lock maxfail 0 lcp-echo-failure 10 lcp-echo-interval 1 mppe required,stateless require-mschap-v2 #refuse-chap #refuse-mschap #refuse-eap #refuse-pap nobsdcomp nodeflate idle 0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org START=70 STOP=30 updown_pptp_interface () { config_get proto "$1" proto if [ "$proto" = "pptp" ]; then if$2 "$1" fi } boot () { config_load network config_foreach updown_pptp_interface interface up } start() { config_load network config_foreach updown_pptp_interface interface up } restart() { config_load network config_foreach updown_pptp_interface interface down config_foreach updown_pptp_interface interface up } stop() { config_load network config_foreach updown_pptp_interface interface down } |
1 2 | $ chmod +x /etc/init.d/pptp $ /etc/init.d/pptp enable # PPTP-Verbindung automatisch mit Systemstart ausführen |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | package 'dhcp' config 'dnsmasq' option 'domainneeded' '1' option 'boguspriv' '1' option 'filterwin2k' '0' option 'localise_queries' '1' option 'local' '/lan/' option 'domain' 'lan' option 'expandhosts' '1' option 'nonegcache' '0' option 'authoritative' '1' option 'readethers' '1' option 'leasefile' '/tmp/dhcp.leases' option 'resolvfile' '/tmp/resolv.conf.auto' # Dhcp-Server fürs Freifunk-Netzwerk aktivieren. config 'dhcp' 'lan' option 'start' '100' option 'limit' '150' option 'leasetime' '12h' option 'interface' 'freifunk' config 'dhcp' 'wan' option 'interface' 'wan' option 'ignore' '1' |
Tipps und Tricks:
1 2 | $ ifup pptp # Starten $ ifdown pptp # Stoppen |
1 | $ pptp 123.123.123.123 user me@my.com password mypassword noauth lock debug |