From: Kunhoon Baik Date: Wed, 30 Mar 2016 08:59:31 +0000 (+0900) Subject: avoid not-allowable mutex lock condition X-Git-Tag: submit/tizen/20160407.093933~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F34%2F64334%2F3;p=platform%2Fkernel%2Flinux-exynos.git avoid not-allowable mutex lock condition Change-Id: Icd2c90535687558aa3f294471edb865ef178a5b4 Signed-off-by: Kazimierz Krosman --- diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 5b8304ded867..2a38f63adf43 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -943,7 +943,6 @@ static ssize_t kmsg_read(struct log_buffer *log_b, struct file *file, ret = wait_event_interruptible(log_b->wait, user->seq != log_b->next_seq); } else { - rcu_read_unlock(); kref_get(&log_b->refcount); ret = wait_event_interruptible(log_b->wait, user->seq != log_b->next_seq); @@ -951,7 +950,6 @@ static ssize_t kmsg_read(struct log_buffer *log_b, struct file *file, ret = -ENXIO; if (kref_put(&log_b->refcount, log_buf_release)) ret = -ENXIO; - rcu_read_lock(); } if (ret) goto out; @@ -1056,6 +1054,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, ssize_t ret = -ENXIO; int minor = iminor(file->f_inode); struct log_buffer *log_b; + int found = 0; if (!user) return -EBADF; @@ -1066,11 +1065,17 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, rcu_read_lock(); list_for_each_entry_rcu(log_b, &log_buf.list, list) { if (log_b->minor == minor) { - ret = kmsg_read(log_b, file, buf, count, ppos); + found = 1; + kref_get(&log_b->refcount); break; } } rcu_read_unlock(); + + if(found){ + ret = kmsg_read(log_b, file, buf, count, ppos); + kref_put(&log_b->refcount, log_buf_release); + } return ret; } @@ -1210,6 +1215,7 @@ static int devkmsg_open(struct inode *inode, struct file *file) int ret = -ENXIO; int minor = iminor(file->f_inode); struct log_buffer *log_b; + int found = 0; /* write-only does not need any file context */ if ((file->f_flags & O_ACCMODE) == O_WRONLY) @@ -1227,11 +1233,17 @@ static int devkmsg_open(struct inode *inode, struct file *file) rcu_read_lock(); list_for_each_entry_rcu(log_b, &log_buf.list, list) { if (log_b->minor == minor) { - ret = kmsg_open(log_b, file); + found = 1; + kref_get(&log_b->refcount); break; } } rcu_read_unlock(); + + if(found){ + ret = kmsg_open(log_b, file); + kref_put(&log_b->refcount, log_buf_release); + } return ret; }