summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2013-06-20 18:05:56 -0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-07 16:02:15 -0700
commit595cfbc5ae5bfaefa29b57a3f4dec04b76e108c5 (patch)
tree0b2431ffab89334b8e94ea3413ad25fbf68a2c5f
parent18c51452a1424cdf55ca9e6de2e4c75604272bb5 (diff)
downloadlinux-stable-595cfbc5ae5bfaefa29b57a3f4dec04b76e108c5.tar.gz
linux-stable-595cfbc5ae5bfaefa29b57a3f4dec04b76e108c5.tar.bz2
linux-stable-595cfbc5ae5bfaefa29b57a3f4dec04b76e108c5.zip
vgacon.c: add cond reschedule points in vgacon_do_font_op
commit 7e6d72c15ff4cc0c27573901bb05f9eddbd71ed4 upstream. Booting a 64-vcpu KVM guest, with CONFIG_PREEMPT_VOLUNTARY, can result in a soft lockup: BUG: soft lockup - CPU#41 stuck for 67s! [setfont:1505] RIP: 0010:[<ffffffff812c48da>] [<ffffffff812c48da>] vgacon_do_font_op.clone.0+0x1ba/0x550 This is due to the 8192 (cmapsz) IO operations taking longer than expected due to lock contention in QEMU. Add conditional resched points in between writes allowing other tasks to execute. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com> [bwh: Backported to 3.2: add #include <linux/sched.h>, already present upstream] Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Cc: Qiang Huang <h.huangqiang@huawei.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/video/console/vgacon.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 5855d17d19ac..9d8feac67637 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -42,6 +42,7 @@
#include <linux/kd.h>
#include <linux/slab.h>
#include <linux/vt_kern.h>
+#include <linux/sched.h>
#include <linux/selection.h>
#include <linux/spinlock.h>
#include <linux/ioport.h>
@@ -1124,11 +1125,15 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
if (arg) {
if (set)
- for (i = 0; i < cmapsz; i++)
+ for (i = 0; i < cmapsz; i++) {
vga_writeb(arg[i], charmap + i);
+ cond_resched();
+ }
else
- for (i = 0; i < cmapsz; i++)
+ for (i = 0; i < cmapsz; i++) {
arg[i] = vga_readb(charmap + i);
+ cond_resched();
+ }
/*
* In 512-character mode, the character map is not contiguous if
@@ -1139,11 +1144,15 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
charmap += 2 * cmapsz;
arg += cmapsz;
if (set)
- for (i = 0; i < cmapsz; i++)
+ for (i = 0; i < cmapsz; i++) {
vga_writeb(arg[i], charmap + i);
+ cond_resched();
+ }
else
- for (i = 0; i < cmapsz; i++)
+ for (i = 0; i < cmapsz; i++) {
arg[i] = vga_readb(charmap + i);
+ cond_resched();
+ }
}
}