summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorIvan Vecera <ivecera@redhat.com>2026-02-03 18:40:00 +0100
committerPaolo Abeni <pabeni@redhat.com>2026-02-05 15:57:46 +0100
commit3c0da1030c58b0f1ee4d8ef4722466f8ce734a53 (patch)
treef5d235e4e6c1db8a45cb280d6e215337d83a5afd /include/linux
parent729f5e0153bda8c0423fb7c5795865b6b77ca050 (diff)
dpll: Add reference count tracking support
Add support for the REF_TRACKER infrastructure to the DPLL subsystem. When enabled, this allows developers to track and debug reference counting leaks or imbalances for dpll_device and dpll_pin objects. It records stack traces for every get/put operation and exposes this information via debugfs at: /sys/kernel/debug/ref_tracker/dpll_device_* /sys/kernel/debug/ref_tracker/dpll_pin_* The following API changes are made to support this: 1. dpll_device_get() / dpll_device_put() now accept a 'dpll_tracker *' (which is a typedef to 'struct ref_tracker *' when enabled, or an empty struct otherwise). 2. dpll_pin_get() / dpll_pin_put() and fwnode_dpll_pin_find() similarly accept the tracker argument. 3. Internal registration structures now hold a tracker to associate the reference held by the registration with the specific owner. All existing in-tree drivers (ice, mlx5, ptp_ocp, zl3073x) are updated to pass NULL for the new tracker argument, maintaining current behavior while enabling future debugging capabilities. Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Co-developed-by: Petr Oros <poros@redhat.com> Signed-off-by: Petr Oros <poros@redhat.com> Signed-off-by: Ivan Vecera <ivecera@redhat.com> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> Link: https://patch.msgid.link/20260203174002.705176-8-ivecera@redhat.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/dpll.h21
1 files changed, 15 insertions, 6 deletions
diff --git a/include/linux/dpll.h b/include/linux/dpll.h
index 8fff048131f1..2ce295b46b8c 100644
--- a/include/linux/dpll.h
+++ b/include/linux/dpll.h
@@ -18,6 +18,7 @@ struct dpll_device;
struct dpll_pin;
struct dpll_pin_esync;
struct fwnode_handle;
+struct ref_tracker;
struct dpll_device_ops {
int (*mode_get)(const struct dpll_device *dpll, void *dpll_priv,
@@ -173,6 +174,12 @@ struct dpll_pin_properties {
u32 phase_gran;
};
+#ifdef CONFIG_DPLL_REFCNT_TRACKER
+typedef struct ref_tracker *dpll_tracker;
+#else
+typedef struct {} dpll_tracker;
+#endif
+
#define DPLL_DEVICE_CREATED 1
#define DPLL_DEVICE_DELETED 2
#define DPLL_DEVICE_CHANGED 3
@@ -205,7 +212,8 @@ size_t dpll_netdev_pin_handle_size(const struct net_device *dev);
int dpll_netdev_add_pin_handle(struct sk_buff *msg,
const struct net_device *dev);
-struct dpll_pin *fwnode_dpll_pin_find(struct fwnode_handle *fwnode);
+struct dpll_pin *fwnode_dpll_pin_find(struct fwnode_handle *fwnode,
+ dpll_tracker *tracker);
#else
static inline void
dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin) { }
@@ -223,16 +231,17 @@ dpll_netdev_add_pin_handle(struct sk_buff *msg, const struct net_device *dev)
}
static inline struct dpll_pin *
-fwnode_dpll_pin_find(struct fwnode_handle *fwnode)
+fwnode_dpll_pin_find(struct fwnode_handle *fwnode, dpll_tracker *tracker)
{
return NULL;
}
#endif
struct dpll_device *
-dpll_device_get(u64 clock_id, u32 dev_driver_id, struct module *module);
+dpll_device_get(u64 clock_id, u32 dev_driver_id, struct module *module,
+ dpll_tracker *tracker);
-void dpll_device_put(struct dpll_device *dpll);
+void dpll_device_put(struct dpll_device *dpll, dpll_tracker *tracker);
int dpll_device_register(struct dpll_device *dpll, enum dpll_type type,
const struct dpll_device_ops *ops, void *priv);
@@ -244,7 +253,7 @@ void dpll_device_unregister(struct dpll_device *dpll,
struct dpll_pin *
dpll_pin_get(u64 clock_id, u32 dev_driver_id, struct module *module,
- const struct dpll_pin_properties *prop);
+ const struct dpll_pin_properties *prop, dpll_tracker *tracker);
int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
const struct dpll_pin_ops *ops, void *priv);
@@ -252,7 +261,7 @@ int dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
void dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin,
const struct dpll_pin_ops *ops, void *priv);
-void dpll_pin_put(struct dpll_pin *pin);
+void dpll_pin_put(struct dpll_pin *pin, dpll_tracker *tracker);
void dpll_pin_fwnode_set(struct dpll_pin *pin, struct fwnode_handle *fwnode);