summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-07-06 11:04:13 +0200
committerKay Sievers <kay@vrfy.org>2012-07-06 11:04:13 +0200
commit116949cb68ef5c93210783dd88c4db3c11c4f610 (patch)
tree6d7662bc04cb5aad2ab95af2c639209c6e60c479
parentfda71f238b68562454f806b2abc9b4f873327f0f (diff)
downloadpatches-116949cb68ef5c93210783dd88c4db3c11c4f610.tar.gz
add spinlock patch
-rw-r--r--00-kmsg-spinlock_irq.patch112
-rw-r--r--01-kmsg-escape.patch (renamed from kmsg-escape.patch)0
-rw-r--r--02-kmsg-facility-len.patch (renamed from kmsg-facility-len.patch)0
-rw-r--r--03-kmsg-nonblock-race.patch (renamed from kmsg-nonblock-race.patch)0
-rw-r--r--04-kmsg-cons-fix.patch (renamed from kmsg-cons-fix.patch)0
-rw-r--r--series11
6 files changed, 118 insertions, 5 deletions
diff --git a/00-kmsg-spinlock_irq.patch b/00-kmsg-spinlock_irq.patch
new file mode 100644
index 0000000..7271015
--- /dev/null
+++ b/00-kmsg-spinlock_irq.patch
@@ -0,0 +1,112 @@
+From: liu chuansheng <chuansheng.liu@intel.com>
+Subject: [PATCH] printk: replacing the raw_spin_lock/unlock with raw_spin_lock/unlock_irq
+
+In function devkmsg_read/writev/llseek/poll/open()..., the function
+raw_spin_lock/unlock is used, there is potential deadlock case happening.
+CPU1: thread1 doing the cat /dev/kmsg:
+ raw_spin_lock(&logbuf_lock);
+ while (user->seq == log_next_seq) {
+when thread1 run here, at this time one interrupt is coming on CPU1 and running
+based on this thread,if the interrupt handle called the printk which need the
+logbuf_lock spin also, it will cause deadlock.
+
+So we should use raw_spin_lock/unlock_irq here.
+
+Signed-off-by: liu chuansheng <chuansheng.liu@intel.com>
+---
+ kernel/printk.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/kernel/printk.c
++++ b/kernel/printk.c
+@@ -430,20 +430,20 @@ static ssize_t devkmsg_read(struct file
+ ret = mutex_lock_interruptible(&user->lock);
+ if (ret)
+ return ret;
+- raw_spin_lock(&logbuf_lock);
++ raw_spin_lock_irq(&logbuf_lock);
+ while (user->seq == log_next_seq) {
+ if (file->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
+- raw_spin_unlock(&logbuf_lock);
++ raw_spin_unlock_irq(&logbuf_lock);
+ goto out;
+ }
+
+- raw_spin_unlock(&logbuf_lock);
++ raw_spin_unlock_irq(&logbuf_lock);
+ ret = wait_event_interruptible(log_wait,
+ user->seq != log_next_seq);
+ if (ret)
+ goto out;
+- raw_spin_lock(&logbuf_lock);
++ raw_spin_lock_irq(&logbuf_lock);
+ }
+
+ if (user->seq < log_first_seq) {
+@@ -451,7 +451,7 @@ static ssize_t devkmsg_read(struct file
+ user->idx = log_first_idx;
+ user->seq = log_first_seq;
+ ret = -EPIPE;
+- raw_spin_unlock(&logbuf_lock);
++ raw_spin_unlock_irq(&logbuf_lock);
+ goto out;
+ }
+
+@@ -501,7 +501,7 @@ static ssize_t devkmsg_read(struct file
+
+ user->idx = log_next(user->idx);
+ user->seq++;
+- raw_spin_unlock(&logbuf_lock);
++ raw_spin_unlock_irq(&logbuf_lock);
+
+ if (len > count) {
+ ret = -EINVAL;
+@@ -528,7 +528,7 @@ static loff_t devkmsg_llseek(struct file
+ if (offset)
+ return -ESPIPE;
+
+- raw_spin_lock(&logbuf_lock);
++ raw_spin_lock_irq(&logbuf_lock);
+ switch (whence) {
+ case SEEK_SET:
+ /* the first record */
+@@ -552,7 +552,7 @@ static loff_t devkmsg_llseek(struct file
+ default:
+ ret = -EINVAL;
+ }
+- raw_spin_unlock(&logbuf_lock);
++ raw_spin_unlock_irq(&logbuf_lock);
+ return ret;
+ }
+
+@@ -566,14 +566,14 @@ static unsigned int devkmsg_poll(struct
+
+ poll_wait(file, &log_wait, wait);
+
+- raw_spin_lock(&logbuf_lock);
++ raw_spin_lock_irq(&logbuf_lock);
+ if (user->seq < log_next_seq) {
+ /* return error when data has vanished underneath us */
+ if (user->seq < log_first_seq)
+ ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI;
+ ret = POLLIN|POLLRDNORM;
+ }
+- raw_spin_unlock(&logbuf_lock);
++ raw_spin_unlock_irq(&logbuf_lock);
+
+ return ret;
+ }
+@@ -597,10 +597,10 @@ static int devkmsg_open(struct inode *in
+
+ mutex_init(&user->lock);
+
+- raw_spin_lock(&logbuf_lock);
++ raw_spin_lock_irq(&logbuf_lock);
+ user->idx = log_first_idx;
+ user->seq = log_first_seq;
+- raw_spin_unlock(&logbuf_lock);
++ raw_spin_unlock_irq(&logbuf_lock);
+
+ file->private_data = user;
+ return 0;
diff --git a/kmsg-escape.patch b/01-kmsg-escape.patch
index 7a01496..7a01496 100644
--- a/kmsg-escape.patch
+++ b/01-kmsg-escape.patch
diff --git a/kmsg-facility-len.patch b/02-kmsg-facility-len.patch
index 70fd915..70fd915 100644
--- a/kmsg-facility-len.patch
+++ b/02-kmsg-facility-len.patch
diff --git a/kmsg-nonblock-race.patch b/03-kmsg-nonblock-race.patch
index 6e766f2..6e766f2 100644
--- a/kmsg-nonblock-race.patch
+++ b/03-kmsg-nonblock-race.patch
diff --git a/kmsg-cons-fix.patch b/04-kmsg-cons-fix.patch
index 1109747..1109747 100644
--- a/kmsg-cons-fix.patch
+++ b/04-kmsg-cons-fix.patch
diff --git a/series b/series
index f23d26f..fb9a0a1 100644
--- a/series
+++ b/series
@@ -1,5 +1,6 @@
-kmsg-escape.patch
-kmsg-facility-len.patch
-kmsg-nonblock-race.patch
-test-modules.patch
-kmsg-cons-fix.patch
+#test-modules.patch
+00-kmsg-spinlock_irq.patch
+01-kmsg-escape.patch
+02-kmsg-facility-len.patch
+03-kmsg-nonblock-race.patch
+04-kmsg-cons-fix.patch