aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2012-10-18 16:26:45 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-22 19:53:21 -0400
commit5cff39c69b57df6d7bf4e87f2963571aa4ea6336 (patch)
tree98707dcc865ad2b1ac97751ea83d8f0c35a176e7 /drivers
parent2fc20661e3171d45e8e58a61eb5c6b7d8d614fde (diff)
TTY: tty_buffer, cache pointer to tty->buf
During the move of tty buffers from tty_struct to tty_port, we will need to switch all users of buf to tty->port->buf. There are many functions where this is accessed directly in their code many times. Cache the tty->buf pointer in such functions now and change only single lines in each function in the next patch. Not that it is convenient for the next patch, but the code is now also more readable. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tty/tty_buffer.c132
1 files changed, 76 insertions, 56 deletions
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 6f366f257fba..ddd74d41cbb2 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -29,17 +29,19 @@
29 29
30void tty_buffer_free_all(struct tty_struct *tty) 30void tty_buffer_free_all(struct tty_struct *tty)
31{ 31{
32 struct tty_bufhead *buf = &tty->buf;
32 struct tty_buffer *thead; 33 struct tty_buffer *thead;
33 while ((thead = tty->buf.head) != NULL) { 34
34 tty->buf.head = thead->next; 35 while ((thead = buf->head) != NULL) {
36 buf->head = thead->next;
35 kfree(thead); 37 kfree(thead);
36 } 38 }
37 while ((thead = tty->buf.free) != NULL) { 39 while ((thead = buf->free) != NULL) {
38 tty->buf.free = thead->next; 40 buf->free = thead->next;
39 kfree(thead); 41 kfree(thead);
40 } 42 }
41 tty->buf.tail = NULL; 43 buf->tail = NULL;
42 tty->buf.memory_used = 0; 44 buf->memory_used = 0;
43} 45}
44 46
45/** 47/**
@@ -87,15 +89,17 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size)
87 89
88static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) 90static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
89{ 91{
92 struct tty_bufhead *buf = &tty->buf;
93
90 /* Dumb strategy for now - should keep some stats */ 94 /* Dumb strategy for now - should keep some stats */
91 tty->buf.memory_used -= b->size; 95 buf->memory_used -= b->size;
92 WARN_ON(tty->buf.memory_used < 0); 96 WARN_ON(buf->memory_used < 0);
93 97
94 if (b->size >= 512) 98 if (b->size >= 512)
95 kfree(b); 99 kfree(b);
96 else { 100 else {
97 b->next = tty->buf.free; 101 b->next = buf->free;
98 tty->buf.free = b; 102 buf->free = b;
99 } 103 }
100} 104}
101 105
@@ -112,13 +116,14 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
112 116
113static void __tty_buffer_flush(struct tty_struct *tty) 117static void __tty_buffer_flush(struct tty_struct *tty)
114{ 118{
119 struct tty_bufhead *buf = &tty->buf;
115 struct tty_buffer *thead; 120 struct tty_buffer *thead;
116 121
117 while ((thead = tty->buf.head) != NULL) { 122 while ((thead = buf->head) != NULL) {
118 tty->buf.head = thead->next; 123 buf->head = thead->next;
119 tty_buffer_free(tty, thead); 124 tty_buffer_free(tty, thead);
120 } 125 }
121 tty->buf.tail = NULL; 126 buf->tail = NULL;
122} 127}
123 128
124/** 129/**
@@ -135,21 +140,23 @@ static void __tty_buffer_flush(struct tty_struct *tty)
135void tty_buffer_flush(struct tty_struct *tty) 140void tty_buffer_flush(struct tty_struct *tty)
136{ 141{
137 struct tty_port *port = tty->port; 142 struct tty_port *port = tty->port;
143 struct tty_bufhead *buf = &tty->buf;
138 unsigned long flags; 144 unsigned long flags;
139 spin_lock_irqsave(&tty->buf.lock, flags); 145
146 spin_lock_irqsave(&buf->lock, flags);
140 147
141 /* If the data is being pushed to the tty layer then we can't 148 /* If the data is being pushed to the tty layer then we can't
142 process it here. Instead set a flag and the flush_to_ldisc 149 process it here. Instead set a flag and the flush_to_ldisc
143 path will process the flush request before it exits */ 150 path will process the flush request before it exits */
144 if (test_bit(TTYP_FLUSHING, &port->iflags)) { 151 if (test_bit(TTYP_FLUSHING, &port->iflags)) {
145 set_bit(TTYP_FLUSHPENDING, &port->iflags); 152 set_bit(TTYP_FLUSHPENDING, &port->iflags);
146 spin_unlock_irqrestore(&tty->buf.lock, flags); 153 spin_unlock_irqrestore(&buf->lock, flags);
147 wait_event(tty->read_wait, 154 wait_event(tty->read_wait,
148 test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0); 155 test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0);
149 return; 156 return;
150 } else 157 } else
151 __tty_buffer_flush(tty); 158 __tty_buffer_flush(tty);
152 spin_unlock_irqrestore(&tty->buf.lock, flags); 159 spin_unlock_irqrestore(&buf->lock, flags);
153} 160}
154 161
155/** 162/**
@@ -197,12 +204,14 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size)
197 */ 204 */
198static int __tty_buffer_request_room(struct tty_struct *tty, size_t size) 205static int __tty_buffer_request_room(struct tty_struct *tty, size_t size)
199{ 206{
207 struct tty_bufhead *buf = &tty->buf;
200 struct tty_buffer *b, *n; 208 struct tty_buffer *b, *n;
201 int left; 209 int left;
202 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to 210 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to
203 remove this conditional if its worth it. This would be invisible 211 remove this conditional if its worth it. This would be invisible
204 to the callers */ 212 to the callers */
205 if ((b = tty->buf.tail) != NULL) 213 b = buf->tail;
214 if (b != NULL)
206 left = b->size - b->used; 215 left = b->size - b->used;
207 else 216 else
208 left = 0; 217 left = 0;
@@ -214,8 +223,8 @@ static int __tty_buffer_request_room(struct tty_struct *tty, size_t size)
214 b->next = n; 223 b->next = n;
215 b->commit = b->used; 224 b->commit = b->used;
216 } else 225 } else
217 tty->buf.head = n; 226 buf->head = n;
218 tty->buf.tail = n; 227 buf->tail = n;
219 } else 228 } else
220 size = left; 229 size = left;
221 } 230 }
@@ -262,6 +271,7 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room);
262int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, 271int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
263 const unsigned char *chars, char flag, size_t size) 272 const unsigned char *chars, char flag, size_t size)
264{ 273{
274 struct tty_bufhead *buf = &tty->buf;
265 int copied = 0; 275 int copied = 0;
266 do { 276 do {
267 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); 277 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
@@ -269,18 +279,18 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty,
269 unsigned long flags; 279 unsigned long flags;
270 struct tty_buffer *tb; 280 struct tty_buffer *tb;
271 281
272 spin_lock_irqsave(&tty->buf.lock, flags); 282 spin_lock_irqsave(&buf->lock, flags);
273 space = __tty_buffer_request_room(tty, goal); 283 space = __tty_buffer_request_room(tty, goal);
274 tb = tty->buf.tail; 284 tb = buf->tail;
275 /* If there is no space then tb may be NULL */ 285 /* If there is no space then tb may be NULL */
276 if (unlikely(space == 0)) { 286 if (unlikely(space == 0)) {
277 spin_unlock_irqrestore(&tty->buf.lock, flags); 287 spin_unlock_irqrestore(&buf->lock, flags);
278 break; 288 break;
279 } 289 }
280 memcpy(tb->char_buf_ptr + tb->used, chars, space); 290 memcpy(tb->char_buf_ptr + tb->used, chars, space);
281 memset(tb->flag_buf_ptr + tb->used, flag, space); 291 memset(tb->flag_buf_ptr + tb->used, flag, space);
282 tb->used += space; 292 tb->used += space;
283 spin_unlock_irqrestore(&tty->buf.lock, flags); 293 spin_unlock_irqrestore(&buf->lock, flags);
284 copied += space; 294 copied += space;
285 chars += space; 295 chars += space;
286 /* There is a small chance that we need to split the data over 296 /* There is a small chance that we need to split the data over
@@ -307,6 +317,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag);
307int tty_insert_flip_string_flags(struct tty_struct *tty, 317int tty_insert_flip_string_flags(struct tty_struct *tty,
308 const unsigned char *chars, const char *flags, size_t size) 318 const unsigned char *chars, const char *flags, size_t size)
309{ 319{
320 struct tty_bufhead *buf = &tty->buf;
310 int copied = 0; 321 int copied = 0;
311 do { 322 do {
312 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); 323 int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE);
@@ -314,18 +325,18 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
314 unsigned long __flags; 325 unsigned long __flags;
315 struct tty_buffer *tb; 326 struct tty_buffer *tb;
316 327
317 spin_lock_irqsave(&tty->buf.lock, __flags); 328 spin_lock_irqsave(&buf->lock, __flags);
318 space = __tty_buffer_request_room(tty, goal); 329 space = __tty_buffer_request_room(tty, goal);
319 tb = tty->buf.tail; 330 tb = buf->tail;
320 /* If there is no space then tb may be NULL */ 331 /* If there is no space then tb may be NULL */
321 if (unlikely(space == 0)) { 332 if (unlikely(space == 0)) {
322 spin_unlock_irqrestore(&tty->buf.lock, __flags); 333 spin_unlock_irqrestore(&buf->lock, __flags);
323 break; 334 break;
324 } 335 }
325 memcpy(tb->char_buf_ptr + tb->used, chars, space); 336 memcpy(tb->char_buf_ptr + tb->used, chars, space);
326 memcpy(tb->flag_buf_ptr + tb->used, flags, space); 337 memcpy(tb->flag_buf_ptr + tb->used, flags, space);
327 tb->used += space; 338 tb->used += space;
328 spin_unlock_irqrestore(&tty->buf.lock, __flags); 339 spin_unlock_irqrestore(&buf->lock, __flags);
329 copied += space; 340 copied += space;
330 chars += space; 341 chars += space;
331 flags += space; 342 flags += space;
@@ -351,12 +362,14 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags);
351 362
352void tty_schedule_flip(struct tty_struct *tty) 363void tty_schedule_flip(struct tty_struct *tty)
353{ 364{
365 struct tty_bufhead *buf = &tty->buf;
354 unsigned long flags; 366 unsigned long flags;
355 spin_lock_irqsave(&tty->buf.lock, flags); 367
356 if (tty->buf.tail != NULL) 368 spin_lock_irqsave(&buf->lock, flags);
357 tty->buf.tail->commit = tty->buf.tail->used; 369 if (buf->tail != NULL)
358 spin_unlock_irqrestore(&tty->buf.lock, flags); 370 buf->tail->commit = buf->tail->used;
359 schedule_work(&tty->buf.work); 371 spin_unlock_irqrestore(&buf->lock, flags);
372 schedule_work(&buf->work);
360} 373}
361EXPORT_SYMBOL(tty_schedule_flip); 374EXPORT_SYMBOL(tty_schedule_flip);
362 375
@@ -378,20 +391,21 @@ EXPORT_SYMBOL(tty_schedule_flip);
378int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, 391int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars,
379 size_t size) 392 size_t size)
380{ 393{
394 struct tty_bufhead *buf = &tty->buf;
381 int space; 395 int space;
382 unsigned long flags; 396 unsigned long flags;
383 struct tty_buffer *tb; 397 struct tty_buffer *tb;
384 398
385 spin_lock_irqsave(&tty->buf.lock, flags); 399 spin_lock_irqsave(&buf->lock, flags);
386 space = __tty_buffer_request_room(tty, size); 400 space = __tty_buffer_request_room(tty, size);
387 401
388 tb = tty->buf.tail; 402 tb = buf->tail;
389 if (likely(space)) { 403 if (likely(space)) {
390 *chars = tb->char_buf_ptr + tb->used; 404 *chars = tb->char_buf_ptr + tb->used;
391 memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); 405 memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space);
392 tb->used += space; 406 tb->used += space;
393 } 407 }
394 spin_unlock_irqrestore(&tty->buf.lock, flags); 408 spin_unlock_irqrestore(&buf->lock, flags);
395 return space; 409 return space;
396} 410}
397EXPORT_SYMBOL_GPL(tty_prepare_flip_string); 411EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
@@ -415,20 +429,21 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string);
415int tty_prepare_flip_string_flags(struct tty_struct *tty, 429int tty_prepare_flip_string_flags(struct tty_struct *tty,
416 unsigned char **chars, char **flags, size_t size) 430 unsigned char **chars, char **flags, size_t size)
417{ 431{
432 struct tty_bufhead *buf = &tty->buf;
418 int space; 433 int space;
419 unsigned long __flags; 434 unsigned long __flags;
420 struct tty_buffer *tb; 435 struct tty_buffer *tb;
421 436
422 spin_lock_irqsave(&tty->buf.lock, __flags); 437 spin_lock_irqsave(&buf->lock, __flags);
423 space = __tty_buffer_request_room(tty, size); 438 space = __tty_buffer_request_room(tty, size);
424 439
425 tb = tty->buf.tail; 440 tb = buf->tail;
426 if (likely(space)) { 441 if (likely(space)) {
427 *chars = tb->char_buf_ptr + tb->used; 442 *chars = tb->char_buf_ptr + tb->used;
428 *flags = tb->flag_buf_ptr + tb->used; 443 *flags = tb->flag_buf_ptr + tb->used;
429 tb->used += space; 444 tb->used += space;
430 } 445 }
431 spin_unlock_irqrestore(&tty->buf.lock, __flags); 446 spin_unlock_irqrestore(&buf->lock, __flags);
432 return space; 447 return space;
433} 448}
434EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); 449EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
@@ -452,6 +467,7 @@ static void flush_to_ldisc(struct work_struct *work)
452 struct tty_struct *tty = 467 struct tty_struct *tty =
453 container_of(work, struct tty_struct, buf.work); 468 container_of(work, struct tty_struct, buf.work);
454 struct tty_port *port = tty->port; 469 struct tty_port *port = tty->port;
470 struct tty_bufhead *buf = &tty->buf;
455 unsigned long flags; 471 unsigned long flags;
456 struct tty_ldisc *disc; 472 struct tty_ldisc *disc;
457 473
@@ -459,11 +475,11 @@ static void flush_to_ldisc(struct work_struct *work)
459 if (disc == NULL) /* !TTY_LDISC */ 475 if (disc == NULL) /* !TTY_LDISC */
460 return; 476 return;
461 477
462 spin_lock_irqsave(&tty->buf.lock, flags); 478 spin_lock_irqsave(&buf->lock, flags);
463 479
464 if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) { 480 if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) {
465 struct tty_buffer *head; 481 struct tty_buffer *head;
466 while ((head = tty->buf.head) != NULL) { 482 while ((head = buf->head) != NULL) {
467 int count; 483 int count;
468 char *char_buf; 484 char *char_buf;
469 unsigned char *flag_buf; 485 unsigned char *flag_buf;
@@ -472,7 +488,7 @@ static void flush_to_ldisc(struct work_struct *work)
472 if (!count) { 488 if (!count) {
473 if (head->next == NULL) 489 if (head->next == NULL)
474 break; 490 break;
475 tty->buf.head = head->next; 491 buf->head = head->next;
476 tty_buffer_free(tty, head); 492 tty_buffer_free(tty, head);
477 continue; 493 continue;
478 } 494 }
@@ -488,10 +504,10 @@ static void flush_to_ldisc(struct work_struct *work)
488 char_buf = head->char_buf_ptr + head->read; 504 char_buf = head->char_buf_ptr + head->read;
489 flag_buf = head->flag_buf_ptr + head->read; 505 flag_buf = head->flag_buf_ptr + head->read;
490 head->read += count; 506 head->read += count;
491 spin_unlock_irqrestore(&tty->buf.lock, flags); 507 spin_unlock_irqrestore(&buf->lock, flags);
492 disc->ops->receive_buf(tty, char_buf, 508 disc->ops->receive_buf(tty, char_buf,
493 flag_buf, count); 509 flag_buf, count);
494 spin_lock_irqsave(&tty->buf.lock, flags); 510 spin_lock_irqsave(&buf->lock, flags);
495 } 511 }
496 clear_bit(TTYP_FLUSHING, &port->iflags); 512 clear_bit(TTYP_FLUSHING, &port->iflags);
497 } 513 }
@@ -503,7 +519,7 @@ static void flush_to_ldisc(struct work_struct *work)
503 clear_bit(TTYP_FLUSHPENDING, &port->iflags); 519 clear_bit(TTYP_FLUSHPENDING, &port->iflags);
504 wake_up(&tty->read_wait); 520 wake_up(&tty->read_wait);
505 } 521 }
506 spin_unlock_irqrestore(&tty->buf.lock, flags); 522 spin_unlock_irqrestore(&buf->lock, flags);
507 523
508 tty_ldisc_deref(disc); 524 tty_ldisc_deref(disc);
509} 525}
@@ -537,16 +553,18 @@ void tty_flush_to_ldisc(struct tty_struct *tty)
537 553
538void tty_flip_buffer_push(struct tty_struct *tty) 554void tty_flip_buffer_push(struct tty_struct *tty)
539{ 555{
556 struct tty_bufhead *buf = &tty->buf;
540 unsigned long flags; 557 unsigned long flags;
541 spin_lock_irqsave(&tty->buf.lock, flags); 558
542 if (tty->buf.tail != NULL) 559 spin_lock_irqsave(&buf->lock, flags);
543 tty->buf.tail->commit = tty->buf.tail->used; 560 if (buf->tail != NULL)
544 spin_unlock_irqrestore(&tty->buf.lock, flags); 561 buf->tail->commit = buf->tail->used;
562 spin_unlock_irqrestore(&buf->lock, flags);
545 563
546 if (tty->low_latency) 564 if (tty->low_latency)
547 flush_to_ldisc(&tty->buf.work); 565 flush_to_ldisc(&buf->work);
548 else 566 else
549 schedule_work(&tty->buf.work); 567 schedule_work(&buf->work);
550} 568}
551EXPORT_SYMBOL(tty_flip_buffer_push); 569EXPORT_SYMBOL(tty_flip_buffer_push);
552 570
@@ -562,11 +580,13 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
562 580
563void tty_buffer_init(struct tty_struct *tty) 581void tty_buffer_init(struct tty_struct *tty)
564{ 582{
565 spin_lock_init(&tty->buf.lock); 583 struct tty_bufhead *buf = &tty->buf;
566 tty->buf.head = NULL; 584
567 tty->buf.tail = NULL; 585 spin_lock_init(&buf->lock);
568 tty->buf.free = NULL; 586 buf->head = NULL;
569 tty->buf.memory_used = 0; 587 buf->tail = NULL;
570 INIT_WORK(&tty->buf.work, flush_to_ldisc); 588 buf->free = NULL;
589 buf->memory_used = 0;
590 INIT_WORK(&buf->work, flush_to_ldisc);
571} 591}
572 592