diff options
author | Kay Sievers <kay@vrfy.org> | 2012-07-06 11:04:13 +0200 |
---|---|---|
committer | Kay Sievers <kay@vrfy.org> | 2012-07-06 11:04:13 +0200 |
commit | 116949cb68ef5c93210783dd88c4db3c11c4f610 (patch) | |
tree | 6d7662bc04cb5aad2ab95af2c639209c6e60c479 | |
parent | fda71f238b68562454f806b2abc9b4f873327f0f (diff) | |
download | patches-116949cb68ef5c93210783dd88c4db3c11c4f610.tar.gz |
add spinlock patch
-rw-r--r-- | 00-kmsg-spinlock_irq.patch | 112 | ||||
-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-- | series | 11 |
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 @@ -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 |