Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] vivid: move PRINTSTR to separate functions

Commit 84cb7be43cec12868e94163c99fdc34c0297c3b8 broke vivid-tpg
(uninitialized variable p).

This patch takes a different approach: four different functions are
created, one for each PRINTSTR version.

In order to avoid the 'the frame size of 1308 bytes is larger than 1024
bytes' warning I had to mark those functions with 'noinline'. For
whatever reason gcc seems to inline this aggressively and it is doing
weird things with the stack.

I tried to read the assembly code, but I couldn't see what exactly it
was doing on the stack.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
c70316f2 64d57022

+81 -47
+81 -47
drivers/media/platform/vivid/vivid-tpg.c
··· 1462 1462 /* need this to do rgb24 rendering */ 1463 1463 typedef struct { u16 __; u8 _; } __packed x24; 1464 1464 1465 - void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], 1466 - int y, int x, char *text) 1467 - { 1468 - int line; 1469 - unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1; 1470 - unsigned div = step; 1471 - unsigned first = 0; 1472 - unsigned len = strlen(text); 1473 - unsigned p; 1474 - 1475 - if (font8x16 == NULL || basep == NULL) 1476 - return; 1477 - 1478 - /* Checks if it is possible to show string */ 1479 - if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width) 1480 - return; 1481 - 1482 - if (len > (tpg->compose.width - x) / 8) 1483 - len = (tpg->compose.width - x) / 8; 1484 - if (tpg->vflip) 1485 - y = tpg->compose.height - y - 16; 1486 - if (tpg->hflip) 1487 - x = tpg->compose.width - x - 8; 1488 - y += tpg->compose.top; 1489 - x += tpg->compose.left; 1490 - if (tpg->field == V4L2_FIELD_BOTTOM) 1491 - first = 1; 1492 - else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT) 1493 - div = 2; 1494 - 1495 - /* Print text */ 1496 - #define PRINTSTR(PIXTYPE) for (p = 0; p < tpg->planes; p++) { \ 1497 - unsigned vdiv = tpg->vdownsampling[p]; \ 1498 - unsigned hdiv = tpg->hdownsampling[p]; \ 1465 + #define PRINTSTR(PIXTYPE) do { \ 1466 + unsigned vdiv = tpg->vdownsampling[p]; \ 1467 + unsigned hdiv = tpg->hdownsampling[p]; \ 1468 + int line; \ 1499 1469 PIXTYPE fg; \ 1500 1470 PIXTYPE bg; \ 1501 1471 memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \ ··· 1516 1546 } \ 1517 1547 } while (0) 1518 1548 1519 - switch (tpg->twopixelsize[p]) { 1520 - case 2: 1521 - PRINTSTR(u8); 1522 - break; 1523 - case 4: 1524 - PRINTSTR(u16); 1525 - break; 1526 - case 6: 1527 - PRINTSTR(x24); 1528 - break; 1529 - case 8: 1530 - PRINTSTR(u32); 1531 - break; 1549 + static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], 1550 + unsigned p, unsigned first, unsigned div, unsigned step, 1551 + int y, int x, char *text, unsigned len) 1552 + { 1553 + PRINTSTR(u8); 1554 + } 1555 + 1556 + static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], 1557 + unsigned p, unsigned first, unsigned div, unsigned step, 1558 + int y, int x, char *text, unsigned len) 1559 + { 1560 + PRINTSTR(u16); 1561 + } 1562 + 1563 + static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], 1564 + unsigned p, unsigned first, unsigned div, unsigned step, 1565 + int y, int x, char *text, unsigned len) 1566 + { 1567 + PRINTSTR(x24); 1568 + } 1569 + 1570 + static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], 1571 + unsigned p, unsigned first, unsigned div, unsigned step, 1572 + int y, int x, char *text, unsigned len) 1573 + { 1574 + PRINTSTR(u32); 1575 + } 1576 + 1577 + void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], 1578 + int y, int x, char *text) 1579 + { 1580 + unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1; 1581 + unsigned div = step; 1582 + unsigned first = 0; 1583 + unsigned len = strlen(text); 1584 + unsigned p; 1585 + 1586 + if (font8x16 == NULL || basep == NULL) 1587 + return; 1588 + 1589 + /* Checks if it is possible to show string */ 1590 + if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width) 1591 + return; 1592 + 1593 + if (len > (tpg->compose.width - x) / 8) 1594 + len = (tpg->compose.width - x) / 8; 1595 + if (tpg->vflip) 1596 + y = tpg->compose.height - y - 16; 1597 + if (tpg->hflip) 1598 + x = tpg->compose.width - x - 8; 1599 + y += tpg->compose.top; 1600 + x += tpg->compose.left; 1601 + if (tpg->field == V4L2_FIELD_BOTTOM) 1602 + first = 1; 1603 + else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT) 1604 + div = 2; 1605 + 1606 + for (p = 0; p < tpg->planes; p++) { 1607 + /* Print text */ 1608 + switch (tpg->twopixelsize[p]) { 1609 + case 2: 1610 + tpg_print_str_2(tpg, basep, p, first, div, step, y, x, 1611 + text, len); 1612 + break; 1613 + case 4: 1614 + tpg_print_str_4(tpg, basep, p, first, div, step, y, x, 1615 + text, len); 1616 + break; 1617 + case 6: 1618 + tpg_print_str_6(tpg, basep, p, first, div, step, y, x, 1619 + text, len); 1620 + break; 1621 + case 8: 1622 + tpg_print_str_8(tpg, basep, p, first, div, step, y, x, 1623 + text, len); 1624 + break; 1625 + } 1532 1626 } 1533 1627 } 1534 1628