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

Configure Feed

Select the types of activity you want to include in your feed.

drm/bridge: Fix refcount shown via debugfs for encoder_bridges_show()

A typical bridge refcount value is 3 after a bridge chain is formed:
- devm_drm_bridge_alloc() initializes the refcount value to be 1.
- drm_bridge_add() gets an additional reference hence 2.
- drm_bridge_attach() gets the third reference hence 3.

This typical refcount value aligns with allbridges_show()'s behaviour.
However, since encoder_bridges_show() uses
drm_for_each_bridge_in_chain_scoped() to automatically get/put the
bridge reference while iterating, a bogus reference is accidentally
got when showing the wrong typical refcount value as 4 to users via
debugfs. Fix this by caching the refcount value returned from
kref_read() while iterating and explicitly decreasing the cached
refcount value by 1 before showing it to users.

Fixes: bd57048e4576 ("drm/bridge: use drm_for_each_bridge_in_chain_scoped()")
Signed-off-by: Liu Ying <victor.liu@nxp.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://patch.msgid.link/20260318-drm-misc-next-2026-03-05-fix-encoder-bridges-refcount-v3-1-147fea581279@nxp.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>

authored by

Liu Ying and committed by
Luca Ceresoli
f078634c 87a70013

+11 -5
+11 -5
drivers/gpu/drm/drm_bridge.c
··· 1569 1569 static void drm_bridge_debugfs_show_bridge(struct drm_printer *p, 1570 1570 struct drm_bridge *bridge, 1571 1571 unsigned int idx, 1572 - bool lingering) 1572 + bool lingering, 1573 + bool scoped) 1573 1574 { 1575 + unsigned int refcount = kref_read(&bridge->refcount); 1576 + 1577 + if (scoped) 1578 + refcount--; 1579 + 1574 1580 drm_printf(p, "bridge[%u]: %ps\n", idx, bridge->funcs); 1575 1581 1576 - drm_printf(p, "\trefcount: %u%s\n", kref_read(&bridge->refcount), 1582 + drm_printf(p, "\trefcount: %u%s\n", refcount, 1577 1583 lingering ? " [lingering]" : ""); 1578 1584 1579 1585 drm_printf(p, "\ttype: [%d] %s\n", ··· 1613 1607 mutex_lock(&bridge_lock); 1614 1608 1615 1609 list_for_each_entry(bridge, &bridge_list, list) 1616 - drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false); 1610 + drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false, false); 1617 1611 1618 1612 list_for_each_entry(bridge, &bridge_lingering_list, list) 1619 - drm_bridge_debugfs_show_bridge(&p, bridge, idx++, true); 1613 + drm_bridge_debugfs_show_bridge(&p, bridge, idx++, true, false); 1620 1614 1621 1615 mutex_unlock(&bridge_lock); 1622 1616 ··· 1631 1625 unsigned int idx = 0; 1632 1626 1633 1627 drm_for_each_bridge_in_chain_scoped(encoder, bridge) 1634 - drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false); 1628 + drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false, true); 1635 1629 1636 1630 return 0; 1637 1631 }