* [PATCH v5 0/2] media: ipu-bridge: survive module unload and reuse the software nodes on rebind
@ 2026-10-26 8:25 D. Manresa
2026-10-26 8:25 ` [PATCH v5 1/2] media: ipu-bridge: don't reference the module image from software nodes D. Manresa
2026-10-26 8:25 ` [PATCH v5 2/2] media: ipu-bridge: reuse the software nodes on rebind D. Manresa
0 siblings, 2 replies; 3+ messages in thread
From: D. Manresa @ 2026-10-26 8:25 UTC (permalink / raw)
To: sakari.ailus, johannes.goede, dan.scally
Cc: mchehab, fernandorimoli11, lsa.uz, linux-media, linux-kernel
Hello,
v5 fixes a reference counting bug that 2/2 had in v4, and carries
Fernando Rimoli's Tested-by on 1/2.
A correction before anything else: in v4 I wrote that the Surface Pro 7+
was leaving my hands and that the patches were compile-tested only. It
is still here for a few more days, so this version is tested on it.
2/2 as posted in v4 dropped the reference software_node_find_by_name()
takes, on the grounds that the node is never unregistered. That is the
wrong half of the story. software_node_notify() resolves a device's
software node through dev_fwnode(dev)->secondary, which the IPU does not
have yet when device_add() calls it, so it takes no reference;
software_node_notify_remove() does resolve it on the next device_del()
and calls swnode_put(). The reuse path has to hand its reference to that
put.
Measured on the Pro 7+ with a module that reads the kobject reference
count of the INT343E node directly:
v4 2/2 as posted 4 -> 3 -> 2 -> 1, and the node is gone from
/sys/kernel/software_nodes on the fourth
remove/rescan cycle. Reproduced twice.
v5 2/2 4 -> 3 on each PCI remove, back to 4 on each
bind, over 16 cycles, children intact.
The decrement happens at the PCI remove, not at the module unload, and
only the IPU node is affected: the sensors' own nodes (INT33BE-4,
INT347A-1, INT347E-5 here) hold steady, since those devices are never
deleted. A remove that follows a failed bind costs nothing, because
there is no secondary fwnode left for software_node_notify_remove() to
resolve.
The series itself, on a Surface Pro 7+ (IPU6 Tiger Lake, 8086:9a19 at
0000:00:05.0, OV5693 + OV8865 + OV7251) running 6.19 with the equivalent
change:
- without the series, the PCI remove -> modprobe -r -> rescan ->
modprobe sequence fails exactly as the 2/2 commit message describes,
with -EEXIST, and the cameras stay dead until a reboot;
- with it, four cycles complete and all three sensors stream after
each one.
Two things that cost me time, in case they would cost a reviewer the
same:
- modprobe -r intel_ipu6_isys intel_ipu6 leaves ipu_bridge resident at
reference count 0. Without an explicit modprobe -r ipu_bridge the
module image is never freed and neither failure reproduces.
- the reuse path logs at dev_dbg(), so it is invisible without
dyndbg=+p.
The asymmetry underneath this is in drivers/base, not here: a software
node that becomes a device's secondary fwnode after device_add() gets a
swnode_put() at device_del() that no swnode_get() ever matched. I am
accounting for it in the bridge because that is where this series is,
but if it should be balanced in software_node_notify() instead, say so
and I will send that.
Unrelated but worth flagging: Sergey Lebedev's "Add the Surface Pro 11
infrared illuminator" series touches the same two lines 1/2 does
(dev_properties[3] and the "lens-focus" name), so whichever of the two
lands second needs a trivial rebase.
Changes since v4:
- 2/2: keep the reference from software_node_find_by_name() instead of
dropping it, and say in the comment what consumes it;
- 2/2: commit message notes the reference counting;
- 1/2: Fernando Rimoli's Tested-by (Surface Pro 9);
- tested on hardware, where v4 was compile-tested only.
Changes since v3:
- 1/2 and 2/2: commit messages cut down;
- 1/2: lens_focus moved into struct ipu_property_names and link_freqs
into struct ipu_sensor;
- 2/2: reuse-path comment shortened.
v4: https://lore.kernel.org/linux-media/20261010155626.2766298-1-dmanresa@gmail.com/
v3: https://lore.kernel.org/linux-media/20261008132614.2456716-1-dmanresa@gmail.com/
Thanks,
D. Manresa
D. Manresa (2):
media: ipu-bridge: don't reference the module image from software
nodes
media: ipu-bridge: reuse the software nodes on rebind
drivers/media/pci/intel/ipu-bridge.c | 34 +++++++++++++++++++++++++++++++---
include/media/ipu-bridge.h | 6 ++++++
2 files changed, 37 insertions(+), 3 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v5 1/2] media: ipu-bridge: don't reference the module image from software nodes
2026-10-26 8:25 [PATCH v5 0/2] media: ipu-bridge: survive module unload and reuse the software nodes on rebind D. Manresa
@ 2026-10-26 8:25 ` D. Manresa
2026-10-26 8:25 ` [PATCH v5 2/2] media: ipu-bridge: reuse the software nodes on rebind D. Manresa
1 sibling, 0 replies; 3+ messages in thread
From: D. Manresa @ 2026-10-26 8:25 UTC (permalink / raw)
To: sakari.ailus, johannes.goede, dan.scally
Cc: mchehab, fernandorimoli11, lsa.uz, linux-media, linux-kernel
The software nodes the bridge registers are deliberately never
unregistered, so that a later rebind can reuse them. Nothing reachable
from them may therefore point into the module image, but two properties
still do: the "link-frequencies" values point at cfg->link_freqs in
ipu_supported_sensors[], and the "lens-focus" property name is a string
literal.
Both dangle once the module is unloaded. Re-probing sensor drivers then
read poisoned link frequencies from the surviving nodes and fail:
ov5693: supported link freq 419200000 not found
Copy both into struct ipu_sensor, where the other property names and
values already live.
Assisted-by: LLM
Fixes: 803abec64ef9 ("media: ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver")
Fixes: 68b9bcc8a534 ("media: ipu3-cio2: Add support for instantiating i2c-clients for VCMs")
Tested-by: Fernando Rimoli <fernandorimoli11@gmail.com> # Surface Pro 9, IPU6 (8086:465d); boot and sensor rebind, not unload or rescan
Signed-off-by: D. Manresa <dmanresa@gmail.com>
---
drivers/media/pci/intel/ipu-bridge.c | 12 +++++++++---
include/media/ipu-bridge.h | 6 ++++++
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
index 3739c4a..aea4699 100644
--- a/drivers/media/pci/intel/ipu-bridge.c
+++ b/drivers/media/pci/intel/ipu-bridge.c
@@ -290,6 +290,7 @@ static const struct ipu_property_names prop_names = {
.remote_endpoint = "remote-endpoint",
.link_frequencies = "link-frequencies",
.clock_noncontinuous = "clock-noncontinuous",
+ .lens_focus = "lens-focus",
};
static const char * const ipu_vcm_types[] = {
@@ -623,7 +624,8 @@ static void ipu_bridge_create_fwnode_properties(
sensor->vcm_ref[0] =
SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_VCM]);
sensor->dev_properties[3] =
- PROPERTY_ENTRY_REF_ARRAY("lens-focus", sensor->vcm_ref);
+ PROPERTY_ENTRY_REF_ARRAY(names->lens_focus,
+ sensor->vcm_ref);
}
sensor->ep_properties[IPU_BRIDGE_NEXT_PROPERTY(i, EP_BUS_TYPE)] =
@@ -636,11 +638,15 @@ static void ipu_bridge_create_fwnode_properties(
PROPERTY_ENTRY_REF_ARRAY(names->remote_endpoint,
sensor->local_ref);
- if (cfg->nr_link_freqs > 0)
+ if (cfg->nr_link_freqs > 0) {
+ memcpy(sensor->link_freqs, cfg->link_freqs,
+ cfg->nr_link_freqs * sizeof(*sensor->link_freqs));
+
sensor->ep_properties[IPU_BRIDGE_NEXT_PROPERTY(i, EP_LINK_FREQUENCIES)] =
PROPERTY_ENTRY_U64_ARRAY_LEN(names->link_frequencies,
- cfg->link_freqs,
+ sensor->link_freqs,
cfg->nr_link_freqs);
+ }
if (cfg->flags & IPU_BR_FL_CSI2_CLK_NONCONTINUOUS)
sensor->ep_properties[IPU_BRIDGE_NEXT_PROPERTY(i, EP_CLOCK_NONCONTINUOUS)] =
diff --git a/include/media/ipu-bridge.h b/include/media/ipu-bridge.h
index 3ef94c2..7c89fb6 100644
--- a/include/media/ipu-bridge.h
+++ b/include/media/ipu-bridge.h
@@ -136,6 +136,7 @@ struct ipu_property_names {
char remote_endpoint[16];
char link_frequencies[17];
char clock_noncontinuous[20];
+ char lens_focus[11];
};
struct ipu_node_names {
@@ -178,6 +179,11 @@ struct ipu_sensor {
const char *vcm_type;
struct ipu_property_names prop_names;
+ /*
+ * The registered software nodes outlive the module, so the property
+ * values they point at must not live in it.
+ */
+ u64 link_freqs[MAX_NUM_LINK_FREQS];
struct property_entry ep_properties[IPU_BRIDGE_EP_NUM_ENTRIES];
struct property_entry dev_properties[5];
struct property_entry ipu_properties[3];
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v5 2/2] media: ipu-bridge: reuse the software nodes on rebind
2026-10-26 8:25 [PATCH v5 0/2] media: ipu-bridge: survive module unload and reuse the software nodes on rebind D. Manresa
2026-10-26 8:25 ` [PATCH v5 1/2] media: ipu-bridge: don't reference the module image from software nodes D. Manresa
@ 2026-10-26 8:25 ` D. Manresa
1 sibling, 0 replies; 3+ messages in thread
From: D. Manresa @ 2026-10-26 8:25 UTC (permalink / raw)
To: sakari.ailus, johannes.goede, dan.scally
Cc: mchehab, fernandorimoli11, lsa.uz, linux-media, linux-kernel
The software nodes are deliberately never unregistered so that a rebind
can reuse them, but ipu_bridge_init() only takes that path when the IPU
kept its secondary fwnode link. Removing and re-scanning the IPU PCI
device clears that link, so the next probe tries to register the IPU HID
node again and fails:
sysfs: cannot create duplicate filename '/kernel/software_nodes/INT343E'
intel-ipu6 0000:00:05.0: Failed to register the IPU HID node
intel-ipu6: probe of 0000:00:05.0 failed with error -17
after which the cameras are unusable until reboot.
Look the registered node up instead and restore the device's secondary
fwnode, keeping the reference the lookup took. software_node_notify()
resolves a device's software node through its secondary fwnode, which is
not set yet when device_add() calls it, so it takes no reference, while
the device_del() of the next remove does resolve it and calls
swnode_put(). Dropping the lookup reference as well would cost the node
one reference per remove/rescan cycle: measured on a Surface Pro 7+, it
was gone from /sys/kernel/software_nodes by the fourth.
Assisted-by: LLM
Fixes: 803abec64ef9 ("media: ipu3-cio2: Add cio2-bridge to ipu3-cio2 driver")
Signed-off-by: D. Manresa <dmanresa@gmail.com>
---
drivers/media/pci/intel/ipu-bridge.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c
index aea4699..45a304c 100644
--- a/drivers/media/pci/intel/ipu-bridge.c
+++ b/drivers/media/pci/intel/ipu-bridge.c
@@ -1098,6 +1098,7 @@ static DEFINE_MUTEX(ipu_bridge_mutex);
int ipu_bridge_init(struct device *dev,
ipu_parse_sensor_fwnode_t parse_sensor_fwnode)
{
+ const struct software_node *ipu_node;
struct fwnode_handle *fwnode;
struct ipu_bridge *bridge;
unsigned int i;
@@ -1108,6 +1109,27 @@ int ipu_bridge_init(struct device *dev,
if (!ipu_bridge_check_fwnode_graph(dev_fwnode(dev)))
return 0;
+ /*
+ * The nodes registered by a previous bind are still there, but the
+ * PCI remove/rescan cycle dropped the IPU's secondary fwnode link to
+ * them. Registering them again would fail with -EEXIST, so reuse
+ * them and restore just that link.
+ */
+ ipu_node = software_node_find_by_name(NULL, IPU_HID);
+ if (ipu_node) {
+ fwnode = software_node_fwnode(ipu_node);
+ /*
+ * The node only becomes the device's secondary fwnode here,
+ * after device_add() has run, so software_node_notify() took
+ * no reference on it. Keep the one from the lookup for the
+ * swnode_put() that software_node_notify_remove() will do on
+ * the next device_del().
+ */
+ set_secondary_fwnode(dev, fwnode);
+ dev_dbg(dev, "Reusing the previously registered software nodes\n");
+ return 0;
+ }
+
if (!ipu_bridge_ivsc_is_ready())
return dev_err_probe(dev, -EPROBE_DEFER,
"waiting for IVSC to become ready\n");
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-26 8:25 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 8:25 [PATCH v5 0/2] media: ipu-bridge: survive module unload and reuse the software nodes on rebind D. Manresa
2026-10-26 8:25 ` [PATCH v5 1/2] media: ipu-bridge: don't reference the module image from software nodes D. Manresa
2026-10-26 8:25 ` [PATCH v5 2/2] media: ipu-bridge: reuse the software nodes on rebind D. Manresa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®