* TTY layer need a lock to copy data to user space
[not found] <950568161.5257116.1417730252670.JavaMail.yahoo@jws10613.mail.bf1.yahoo.com>
@ 2014-12-05 20:16 ` Denis Du
0 siblings, 0 replies; only message in thread
From: Denis Du @ 2014-12-05 20:16 UTC (permalink / raw)
To: gregkh, jslaby; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 649 bytes --]
Hi, Guys:
It was found that the 3.12 kernel tty layer will lose or corrupt data when have a full-duplex communication, especcially in high baudrate, for example 230k for my OMAP5 uart. Eventually I found there is lock missing between copy data to ldisc layer buffer and copy data from the same buffer to user
space. I believe this issue existed since 3.8 kernel(since this kernel , it start to remove most of the spin-locks) and I didn't find any fix even through 3.17 kernel. This patch was tested to be works great with no any data loss again.
I did try to use the existed lock atomic_read_lock, but it doesn’t work.
Denis Du
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Fix-serial-lose-data-by-newlock.patch --]
[-- Type: text/x-patch, Size: 1999 bytes --]
--- drivers/tty/n_tty.c-old 2014-10-16 16:39:35.909350338 -0400
+++ drivers/tty/n_tty.c 2014-10-16 16:49:00.004930469 -0400
@@ -124,6 +124,7 @@
struct mutex atomic_read_lock;
struct mutex output_lock;
+ struct mutex read_buf_lock;
};
static inline size_t read_cnt(struct n_tty_data *ldata)
@@ -1686,9 +1687,11 @@
char *fp, int count)
{
int room, n;
+ struct n_tty_data *ldata = tty->disc_data;
down_read(&tty->termios_rwsem);
+ mutex_lock(&ldata->read_buf_lock);
while (1) {
room = receive_room(tty);
n = min(count, room);
@@ -1703,6 +1706,7 @@
tty->receive_room = room;
n_tty_check_throttle(tty);
+ mutex_unlock(&ldata->read_buf_lock);
up_read(&tty->termios_rwsem);
}
@@ -1713,7 +1717,7 @@
int room, n, rcvd = 0;
down_read(&tty->termios_rwsem);
-
+ mutex_lock(&ldata->read_buf_lock);
while (1) {
room = receive_room(tty);
n = min(count, room);
@@ -1732,6 +1736,7 @@
tty->receive_room = room;
n_tty_check_throttle(tty);
+ mutex_unlock(&ldata->read_buf_lock);
up_read(&tty->termios_rwsem);
return rcvd;
@@ -1880,6 +1885,7 @@
ldata->overrun_time = jiffies;
mutex_init(&ldata->atomic_read_lock);
mutex_init(&ldata->output_lock);
+ mutex_init(&ldata->read_buf_lock);
tty->disc_data = ldata;
reset_buffer_flags(tty->disc_data);
@@ -1945,6 +1951,8 @@
size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
retval = 0;
+
+ mutex_lock(&ldata->read_buf_lock);
n = min(read_cnt(ldata), N_TTY_BUF_SIZE - tail);
n = min(*nr, n);
if (n) {
@@ -1960,6 +1968,7 @@
*b += n;
*nr -= n;
}
+ mutex_unlock(&ldata->read_buf_lock);
return retval;
}
@@ -1990,6 +1999,8 @@
size_t tail;
int ret, found = 0;
bool eof_push = 0;
+
+ mutex_lock(&ldata->read_buf_lock);
/* N.B. avoid overrun if nr == 0 */
n = min(*nr, read_cnt(ldata));
@@ -2049,6 +2060,8 @@
ldata->line_start = ldata->read_tail;
tty_audit_push(tty);
}
+
+ mutex_unlock(&ldata->read_buf_lock);
return eof_push ? -EAGAIN : 0;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2014-12-05 20:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <950568161.5257116.1417730252670.JavaMail.yahoo@jws10613.mail.bf1.yahoo.com>
2014-12-05 20:16 ` TTY layer need a lock to copy data to user space Denis Du
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®