.. | .. |
---|
17 | 17 | #include <linux/delay.h> |
---|
18 | 18 | #include <linux/module.h> |
---|
19 | 19 | #include <linux/ratelimit.h> |
---|
20 | | - |
---|
| 20 | +#include "tty.h" |
---|
21 | 21 | |
---|
22 | 22 | #define MIN_TTYB_SIZE 256 |
---|
23 | 23 | #define TTYB_ALIGN_MASK 255 |
---|
.. | .. |
---|
42 | 42 | * tty_buffer_lock_exclusive - gain exclusive access to buffer |
---|
43 | 43 | * tty_buffer_unlock_exclusive - release exclusive access |
---|
44 | 44 | * |
---|
45 | | - * @port - tty_port owning the flip buffer |
---|
| 45 | + * @port: tty port owning the flip buffer |
---|
46 | 46 | * |
---|
47 | 47 | * Guarantees safe use of the line discipline's receive_buf() method by |
---|
48 | 48 | * excluding the buffer work and any pending flush from using the flip |
---|
.. | .. |
---|
78 | 78 | |
---|
79 | 79 | /** |
---|
80 | 80 | * tty_buffer_space_avail - return unused buffer space |
---|
81 | | - * @port - tty_port owning the flip buffer |
---|
| 81 | + * @port: tty port owning the flip buffer |
---|
82 | 82 | * |
---|
83 | 83 | * Returns the # of bytes which can be written by the driver without |
---|
84 | 84 | * reaching the buffer limit. |
---|
.. | .. |
---|
107 | 107 | |
---|
108 | 108 | /** |
---|
109 | 109 | * tty_buffer_free_all - free buffers used by a tty |
---|
110 | | - * @tty: tty to free from |
---|
| 110 | + * @port: tty port to free from |
---|
111 | 111 | * |
---|
112 | 112 | * Remove all the buffers pending on a tty whether queued with data |
---|
113 | 113 | * or in the free ring. Must be called when the tty is no longer in use |
---|
.. | .. |
---|
118 | 118 | struct tty_bufhead *buf = &port->buf; |
---|
119 | 119 | struct tty_buffer *p, *next; |
---|
120 | 120 | struct llist_node *llist; |
---|
| 121 | + unsigned int freed = 0; |
---|
| 122 | + int still_used; |
---|
121 | 123 | |
---|
122 | 124 | while ((p = buf->head) != NULL) { |
---|
123 | 125 | buf->head = p->next; |
---|
| 126 | + freed += p->size; |
---|
124 | 127 | if (p->size > 0) |
---|
125 | 128 | kfree(p); |
---|
126 | 129 | } |
---|
.. | .. |
---|
132 | 135 | buf->head = &buf->sentinel; |
---|
133 | 136 | buf->tail = &buf->sentinel; |
---|
134 | 137 | |
---|
135 | | - atomic_set(&buf->mem_used, 0); |
---|
| 138 | + still_used = atomic_xchg(&buf->mem_used, 0); |
---|
| 139 | + WARN(still_used != freed, "we still have not freed %d bytes!", |
---|
| 140 | + still_used - freed); |
---|
136 | 141 | } |
---|
137 | 142 | |
---|
138 | 143 | /** |
---|
139 | 144 | * tty_buffer_alloc - allocate a tty buffer |
---|
140 | | - * @tty: tty device |
---|
| 145 | + * @port: tty port |
---|
141 | 146 | * @size: desired size (characters) |
---|
142 | 147 | * |
---|
143 | 148 | * Allocate a new tty buffer to hold the desired number of characters. |
---|
.. | .. |
---|
167 | 172 | have queued and recycle that ? */ |
---|
168 | 173 | if (atomic_read(&port->buf.mem_used) > port->buf.mem_limit) |
---|
169 | 174 | return NULL; |
---|
170 | | - p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); |
---|
| 175 | + p = kmalloc(sizeof(struct tty_buffer) + 2 * size, |
---|
| 176 | + GFP_ATOMIC | __GFP_NOWARN); |
---|
171 | 177 | if (p == NULL) |
---|
172 | 178 | return NULL; |
---|
173 | 179 | |
---|
.. | .. |
---|
179 | 185 | |
---|
180 | 186 | /** |
---|
181 | 187 | * tty_buffer_free - free a tty buffer |
---|
182 | | - * @tty: tty owning the buffer |
---|
| 188 | + * @port: tty port owning the buffer |
---|
183 | 189 | * @b: the buffer to free |
---|
184 | 190 | * |
---|
185 | 191 | * Free a tty buffer, or add it to the free list according to our |
---|
.. | .. |
---|
238 | 244 | |
---|
239 | 245 | /** |
---|
240 | 246 | * tty_buffer_request_room - grow tty buffer if needed |
---|
241 | | - * @tty: tty structure |
---|
| 247 | + * @port: tty port |
---|
242 | 248 | * @size: size desired |
---|
243 | 249 | * @flags: buffer flags if new buffer allocated (default = 0) |
---|
244 | 250 | * |
---|
.. | .. |
---|
389 | 395 | EXPORT_SYMBOL(__tty_insert_flip_char); |
---|
390 | 396 | |
---|
391 | 397 | /** |
---|
392 | | - * tty_schedule_flip - push characters to ldisc |
---|
393 | | - * @port: tty port to push from |
---|
394 | | - * |
---|
395 | | - * Takes any pending buffers and transfers their ownership to the |
---|
396 | | - * ldisc side of the queue. It then schedules those characters for |
---|
397 | | - * processing by the line discipline. |
---|
398 | | - */ |
---|
399 | | - |
---|
400 | | -void tty_schedule_flip(struct tty_port *port) |
---|
401 | | -{ |
---|
402 | | - struct tty_bufhead *buf = &port->buf; |
---|
403 | | - |
---|
404 | | - /* paired w/ acquire in flush_to_ldisc(); ensures |
---|
405 | | - * flush_to_ldisc() sees buffer data. |
---|
406 | | - */ |
---|
407 | | - smp_store_release(&buf->tail->commit, buf->tail->used); |
---|
408 | | - queue_work(system_unbound_wq, &buf->work); |
---|
409 | | -} |
---|
410 | | -EXPORT_SYMBOL(tty_schedule_flip); |
---|
411 | | - |
---|
412 | | -/** |
---|
413 | 398 | * tty_prepare_flip_string - make room for characters |
---|
414 | 399 | * @port: tty port |
---|
415 | 400 | * @chars: return pointer for character write area |
---|
.. | .. |
---|
538 | 523 | |
---|
539 | 524 | } |
---|
540 | 525 | |
---|
| 526 | +static inline void tty_flip_buffer_commit(struct tty_buffer *tail) |
---|
| 527 | +{ |
---|
| 528 | + /* |
---|
| 529 | + * Paired w/ acquire in flush_to_ldisc(); ensures flush_to_ldisc() sees |
---|
| 530 | + * buffer data. |
---|
| 531 | + */ |
---|
| 532 | + smp_store_release(&tail->commit, tail->used); |
---|
| 533 | +} |
---|
| 534 | + |
---|
541 | 535 | /** |
---|
542 | 536 | * tty_flip_buffer_push - terminal |
---|
543 | 537 | * @port: tty port to push |
---|
.. | .. |
---|
551 | 545 | |
---|
552 | 546 | void tty_flip_buffer_push(struct tty_port *port) |
---|
553 | 547 | { |
---|
554 | | - tty_schedule_flip(port); |
---|
| 548 | + struct tty_bufhead *buf = &port->buf; |
---|
| 549 | + |
---|
| 550 | + tty_flip_buffer_commit(buf->tail); |
---|
| 551 | + queue_work(system_unbound_wq, &buf->work); |
---|
555 | 552 | } |
---|
556 | 553 | EXPORT_SYMBOL(tty_flip_buffer_push); |
---|
557 | 554 | |
---|
558 | 555 | /** |
---|
| 556 | + * tty_insert_flip_string_and_push_buffer - add characters to the tty buffer and |
---|
| 557 | + * push |
---|
| 558 | + * @port: tty port |
---|
| 559 | + * @chars: characters |
---|
| 560 | + * @size: size |
---|
| 561 | + * |
---|
| 562 | + * The function combines tty_insert_flip_string() and tty_flip_buffer_push() |
---|
| 563 | + * with the exception of properly holding the @port->lock. |
---|
| 564 | + * |
---|
| 565 | + * To be used only internally (by pty currently). |
---|
| 566 | + * |
---|
| 567 | + * Returns: the number added. |
---|
| 568 | + */ |
---|
| 569 | +int tty_insert_flip_string_and_push_buffer(struct tty_port *port, |
---|
| 570 | + const unsigned char *chars, size_t size) |
---|
| 571 | +{ |
---|
| 572 | + struct tty_bufhead *buf = &port->buf; |
---|
| 573 | + unsigned long flags; |
---|
| 574 | + |
---|
| 575 | + spin_lock_irqsave(&port->lock, flags); |
---|
| 576 | + size = tty_insert_flip_string(port, chars, size); |
---|
| 577 | + if (size) |
---|
| 578 | + tty_flip_buffer_commit(buf->tail); |
---|
| 579 | + spin_unlock_irqrestore(&port->lock, flags); |
---|
| 580 | + |
---|
| 581 | + queue_work(system_unbound_wq, &buf->work); |
---|
| 582 | + |
---|
| 583 | + return size; |
---|
| 584 | +} |
---|
| 585 | + |
---|
| 586 | +/** |
---|
559 | 587 | * tty_buffer_init - prepare a tty buffer structure |
---|
560 | | - * @tty: tty to initialise |
---|
| 588 | + * @port: tty port to initialise |
---|
561 | 589 | * |
---|
562 | 590 | * Set up the initial state of the buffer management for a tty device. |
---|
563 | 591 | * Must be called before the other tty buffer functions are used. |
---|