| .. | .. |
|---|
| 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. |
|---|