projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branches 'for-3.16/i2c-hid', 'for-3.16/rmi4', 'for-3.16/sony' and 'for-3.16...
[firefly-linux-kernel-4.4.55.git]
/
drivers
/
tty
/
tty_buffer.c
diff --git
a/drivers/tty/tty_buffer.c
b/drivers/tty/tty_buffer.c
index 8ebd9f88a6f69ff85f63139944fad2542c789483..cf78d1985cd851fb2b6615054bfabf5a8e3b2b13 100644
(file)
--- a/
drivers/tty/tty_buffer.c
+++ b/
drivers/tty/tty_buffer.c
@@
-258,7
+258,11
@@
static int __tty_buffer_request_room(struct tty_port *port, size_t size,
n->flags = flags;
buf->tail = n;
b->commit = b->used;
n->flags = flags;
buf->tail = n;
b->commit = b->used;
- smp_mb();
+ /* paired w/ barrier in flush_to_ldisc(); ensures the
+ * latest commit value can be read before the head is
+ * advanced to the next buffer
+ */
+ smp_wmb();
b->next = n;
} else if (change)
size = 0;
b->next = n;
} else if (change)
size = 0;
@@
-444,17
+448,24
@@
static void flush_to_ldisc(struct work_struct *work)
while (1) {
struct tty_buffer *head = buf->head;
while (1) {
struct tty_buffer *head = buf->head;
+ struct tty_buffer *next;
int count;
/* Ldisc or user is trying to gain exclusive access */
if (atomic_read(&buf->priority))
break;
int count;
/* Ldisc or user is trying to gain exclusive access */
if (atomic_read(&buf->priority))
break;
+ next = head->next;
+ /* paired w/ barrier in __tty_buffer_request_room();
+ * ensures commit value read is not stale if the head
+ * is advancing to the next buffer
+ */
+ smp_rmb();
count = head->commit - head->read;
if (!count) {
count = head->commit - head->read;
if (!count) {
- if (
head->
next == NULL)
+ if (next == NULL)
break;
break;
- buf->head =
head->
next;
+ buf->head = next;
tty_buffer_free(port, head);
continue;
}
tty_buffer_free(port, head);
continue;
}