>From: Ivan Vecera <[email protected]>
>Sent: Tuesday, February 3, 2026 6:40 PM
>
>Update existing DPLL drivers to utilize the DPLL reference count
>tracking infrastructure.
>
>Add dpll_tracker fields to the drivers' internal device and pin
>structures. Pass pointers to these trackers when calling
>dpll_device_get/put() and dpll_pin_get/put().
>
>This allows developers to inspect the specific references held by this
>driver via debugfs when CONFIG_DPLL_REFCNT_TRACKER is enabled, aiding
>in the debugging of resource leaks.
>
>Reviewed-by: Aleksandr Loktionov <[email protected]>

LGTM,
Reviewed-by: Arkadiusz Kubalewski <[email protected]>

>Signed-off-by: Ivan Vecera <[email protected]>
>---
> drivers/dpll/zl3073x/dpll.c                    | 14 ++++++++------
> drivers/dpll/zl3073x/dpll.h                    |  2 ++
> drivers/net/ethernet/intel/ice/ice_dpll.c      | 15 ++++++++-------
> drivers/net/ethernet/intel/ice/ice_dpll.h      |  4 ++++
> drivers/net/ethernet/mellanox/mlx5/core/dpll.c | 15 +++++++++------
> drivers/ptp/ptp_ocp.c                          | 17 ++++++++++-------
> 6 files changed, 41 insertions(+), 26 deletions(-)
>
>diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
>index 8788bcab7ec53..a99d143a7acde 100644
>--- a/drivers/dpll/zl3073x/dpll.c
>+++ b/drivers/dpll/zl3073x/dpll.c
>@@ -29,6 +29,7 @@
>  * @list: this DPLL pin list entry
>  * @dpll: DPLL the pin is registered to
>  * @dpll_pin: pointer to registered dpll_pin
>+ * @tracker: tracking object for the acquired reference
>  * @label: package label
>  * @dir: pin direction
>  * @id: pin id
>@@ -44,6 +45,7 @@ struct zl3073x_dpll_pin {
>       struct list_head        list;
>       struct zl3073x_dpll     *dpll;
>       struct dpll_pin         *dpll_pin;
>+      dpll_tracker            tracker;
>       char                    label[8];
>       enum dpll_pin_direction dir;
>       u8                      id;
>@@ -1480,7 +1482,7 @@ zl3073x_dpll_pin_register(struct zl3073x_dpll_pin
>*pin, u32 index)
>
>       /* Create or get existing DPLL pin */
>       pin->dpll_pin = dpll_pin_get(zldpll->dev->clock_id, index,
>THIS_MODULE,
>-                                   &props->dpll_props, NULL);
>+                                   &props->dpll_props, &pin->tracker);
>       if (IS_ERR(pin->dpll_pin)) {
>               rc = PTR_ERR(pin->dpll_pin);
>               goto err_pin_get;
>@@ -1503,7 +1505,7 @@ zl3073x_dpll_pin_register(struct zl3073x_dpll_pin
>*pin, u32 index)
>       return 0;
>
> err_register:
>-      dpll_pin_put(pin->dpll_pin, NULL);
>+      dpll_pin_put(pin->dpll_pin, &pin->tracker);
> err_prio_get:
>       pin->dpll_pin = NULL;
> err_pin_get:
>@@ -1534,7 +1536,7 @@ zl3073x_dpll_pin_unregister(struct zl3073x_dpll_pin
>*pin)
>       /* Unregister the pin */
>       dpll_pin_unregister(zldpll->dpll_dev, pin->dpll_pin, ops, pin);
>
>-      dpll_pin_put(pin->dpll_pin, NULL);
>+      dpll_pin_put(pin->dpll_pin, &pin->tracker);
>       pin->dpll_pin = NULL;
> }
>
>@@ -1708,7 +1710,7 @@ zl3073x_dpll_device_register(struct zl3073x_dpll
>*zldpll)
>                                      dpll_mode_refsel);
>
>       zldpll->dpll_dev = dpll_device_get(zldev->clock_id, zldpll->id,
>-                                         THIS_MODULE, NULL);
>+                                         THIS_MODULE, &zldpll->tracker);
>       if (IS_ERR(zldpll->dpll_dev)) {
>               rc = PTR_ERR(zldpll->dpll_dev);
>               zldpll->dpll_dev = NULL;
>@@ -1720,7 +1722,7 @@ zl3073x_dpll_device_register(struct zl3073x_dpll
>*zldpll)
>                                 zl3073x_prop_dpll_type_get(zldev, zldpll->id),
>                                 &zl3073x_dpll_device_ops, zldpll);
>       if (rc) {
>-              dpll_device_put(zldpll->dpll_dev, NULL);
>+              dpll_device_put(zldpll->dpll_dev, &zldpll->tracker);
>               zldpll->dpll_dev = NULL;
>       }
>
>@@ -1743,7 +1745,7 @@ zl3073x_dpll_device_unregister(struct zl3073x_dpll
>*zldpll)
>
>       dpll_device_unregister(zldpll->dpll_dev, &zl3073x_dpll_device_ops,
>                              zldpll);
>-      dpll_device_put(zldpll->dpll_dev, NULL);
>+      dpll_device_put(zldpll->dpll_dev, &zldpll->tracker);
>       zldpll->dpll_dev = NULL;
> }
>
>diff --git a/drivers/dpll/zl3073x/dpll.h b/drivers/dpll/zl3073x/dpll.h
>index e8c39b44b356c..c65c798c37927 100644
>--- a/drivers/dpll/zl3073x/dpll.h
>+++ b/drivers/dpll/zl3073x/dpll.h
>@@ -18,6 +18,7 @@
>  * @check_count: periodic check counter
>  * @phase_monitor: is phase offset monitor enabled
>  * @dpll_dev: pointer to registered DPLL device
>+ * @tracker: tracking object for the acquired reference
>  * @lock_status: last saved DPLL lock status
>  * @pins: list of pins
>  * @change_work: device change notification work
>@@ -31,6 +32,7 @@ struct zl3073x_dpll {
>       u8                              check_count;
>       bool                            phase_monitor;
>       struct dpll_device              *dpll_dev;
>+      dpll_tracker                    tracker;
>       enum dpll_lock_status           lock_status;
>       struct list_head                pins;
>       struct work_struct              change_work;
>diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
>b/drivers/net/ethernet/intel/ice/ice_dpll.c
>index 64b7b045ecd58..4eca62688d834 100644
>--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
>+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
>@@ -2814,7 +2814,7 @@ static void ice_dpll_release_pins(struct
>ice_dpll_pin *pins, int count)
>       int i;
>
>       for (i = 0; i < count; i++)
>-              dpll_pin_put(pins[i].pin, NULL);
>+              dpll_pin_put(pins[i].pin, &pins[i].tracker);
> }
>
> /**
>@@ -2840,7 +2840,7 @@ ice_dpll_get_pins(struct ice_pf *pf, struct
>ice_dpll_pin *pins,
>
>       for (i = 0; i < count; i++) {
>               pins[i].pin = dpll_pin_get(clock_id, i + start_idx,
>THIS_MODULE,
>-                                         &pins[i].prop, NULL);
>+                                         &pins[i].prop, &pins[i].tracker);
>               if (IS_ERR(pins[i].pin)) {
>                       ret = PTR_ERR(pins[i].pin);
>                       goto release_pins;
>@@ -2851,7 +2851,7 @@ ice_dpll_get_pins(struct ice_pf *pf, struct
>ice_dpll_pin *pins,
>
> release_pins:
>       while (--i >= 0)
>-              dpll_pin_put(pins[i].pin, NULL);
>+              dpll_pin_put(pins[i].pin, &pins[i].tracker);
>       return ret;
> }
>
>@@ -3037,7 +3037,7 @@ static void ice_dpll_deinit_rclk_pin(struct ice_pf
>*pf)
>       if (WARN_ON_ONCE(!vsi || !vsi->netdev))
>               return;
>       dpll_netdev_pin_clear(vsi->netdev);
>-      dpll_pin_put(rclk->pin, NULL);
>+      dpll_pin_put(rclk->pin, &rclk->tracker);
> }
>
> /**
>@@ -3247,7 +3247,7 @@ ice_dpll_deinit_dpll(struct ice_pf *pf, struct
>ice_dpll *d, bool cgu)
> {
>       if (cgu)
>               dpll_device_unregister(d->dpll, d->ops, d);
>-      dpll_device_put(d->dpll, NULL);
>+      dpll_device_put(d->dpll, &d->tracker);
> }
>
> /**
>@@ -3271,7 +3271,8 @@ ice_dpll_init_dpll(struct ice_pf *pf, struct
>ice_dpll *d, bool cgu,
>       u64 clock_id = pf->dplls.clock_id;
>       int ret;
>
>-      d->dpll = dpll_device_get(clock_id, d->dpll_idx, THIS_MODULE, NULL);
>+      d->dpll = dpll_device_get(clock_id, d->dpll_idx, THIS_MODULE,
>+                                &d->tracker);
>       if (IS_ERR(d->dpll)) {
>               ret = PTR_ERR(d->dpll);
>               dev_err(ice_pf_to_dev(pf),
>@@ -3287,7 +3288,7 @@ ice_dpll_init_dpll(struct ice_pf *pf, struct
>ice_dpll *d, bool cgu,
>               ice_dpll_update_state(pf, d, true);
>               ret = dpll_device_register(d->dpll, type, ops, d);
>               if (ret) {
>-                      dpll_device_put(d->dpll, NULL);
>+                      dpll_device_put(d->dpll, &d->tracker);
>                       return ret;
>               }
>               d->ops = ops;
>diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.h
>b/drivers/net/ethernet/intel/ice/ice_dpll.h
>index c0da03384ce91..63fac6510df6e 100644
>--- a/drivers/net/ethernet/intel/ice/ice_dpll.h
>+++ b/drivers/net/ethernet/intel/ice/ice_dpll.h
>@@ -23,6 +23,7 @@ enum ice_dpll_pin_sw {
> /** ice_dpll_pin - store info about pins
>  * @pin: dpll pin structure
>  * @pf: pointer to pf, which has registered the dpll_pin
>+ * @tracker: reference count tracker
>  * @idx: ice pin private idx
>  * @num_parents: hols number of parent pins
>  * @parent_idx: hold indexes of parent pins
>@@ -37,6 +38,7 @@ enum ice_dpll_pin_sw {
> struct ice_dpll_pin {
>       struct dpll_pin *pin;
>       struct ice_pf *pf;
>+      dpll_tracker tracker;
>       u8 idx;
>       u8 num_parents;
>       u8 parent_idx[ICE_DPLL_RCLK_NUM_MAX];
>@@ -58,6 +60,7 @@ struct ice_dpll_pin {
> /** ice_dpll - store info required for DPLL control
>  * @dpll: pointer to dpll dev
>  * @pf: pointer to pf, which has registered the dpll_device
>+ * @tracker: reference count tracker
>  * @dpll_idx: index of dpll on the NIC
>  * @input_idx: currently selected input index
>  * @prev_input_idx: previously selected input index
>@@ -76,6 +79,7 @@ struct ice_dpll_pin {
> struct ice_dpll {
>       struct dpll_device *dpll;
>       struct ice_pf *pf;
>+      dpll_tracker tracker;
>       u8 dpll_idx;
>       u8 input_idx;
>       u8 prev_input_idx;
>diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
>b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
>index 541d83e5d7183..3981dd81d4c17 100644
>--- a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
>+++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c
>@@ -9,7 +9,9 @@
>  */
> struct mlx5_dpll {
>       struct dpll_device *dpll;
>+      dpll_tracker dpll_tracker;
>       struct dpll_pin *dpll_pin;
>+      dpll_tracker pin_tracker;
>       struct mlx5_core_dev *mdev;
>       struct workqueue_struct *wq;
>       struct delayed_work work;
>@@ -438,7 +440,8 @@ static int mlx5_dpll_probe(struct auxiliary_device
>*adev,
>       auxiliary_set_drvdata(adev, mdpll);
>
>       /* Multiple mdev instances might share one DPLL device. */
>-      mdpll->dpll = dpll_device_get(clock_id, 0, THIS_MODULE, NULL);
>+      mdpll->dpll = dpll_device_get(clock_id, 0, THIS_MODULE,
>+                                    &mdpll->dpll_tracker);
>       if (IS_ERR(mdpll->dpll)) {
>               err = PTR_ERR(mdpll->dpll);
>               goto err_free_mdpll;
>@@ -452,7 +455,7 @@ static int mlx5_dpll_probe(struct auxiliary_device
>*adev,
>       /* Multiple mdev instances might share one DPLL pin. */
>       mdpll->dpll_pin = dpll_pin_get(clock_id, mlx5_get_dev_index(mdev),
>                                      THIS_MODULE, &mlx5_dpll_pin_properties,
>-                                     NULL);
>+                                     &mdpll->pin_tracker);
>       if (IS_ERR(mdpll->dpll_pin)) {
>               err = PTR_ERR(mdpll->dpll_pin);
>               goto err_unregister_dpll_device;
>@@ -480,11 +483,11 @@ static int mlx5_dpll_probe(struct auxiliary_device
>*adev,
>       dpll_pin_unregister(mdpll->dpll, mdpll->dpll_pin,
>                           &mlx5_dpll_pins_ops, mdpll);
> err_put_dpll_pin:
>-      dpll_pin_put(mdpll->dpll_pin, NULL);
>+      dpll_pin_put(mdpll->dpll_pin, &mdpll->pin_tracker);
> err_unregister_dpll_device:
>       dpll_device_unregister(mdpll->dpll, &mlx5_dpll_device_ops, mdpll);
> err_put_dpll_device:
>-      dpll_device_put(mdpll->dpll, NULL);
>+      dpll_device_put(mdpll->dpll, &mdpll->dpll_tracker);
> err_free_mdpll:
>       kfree(mdpll);
>       return err;
>@@ -500,9 +503,9 @@ static void mlx5_dpll_remove(struct auxiliary_device
>*adev)
>       destroy_workqueue(mdpll->wq);
>       dpll_pin_unregister(mdpll->dpll, mdpll->dpll_pin,
>                           &mlx5_dpll_pins_ops, mdpll);
>-      dpll_pin_put(mdpll->dpll_pin, NULL);
>+      dpll_pin_put(mdpll->dpll_pin, &mdpll->pin_tracker);
>       dpll_device_unregister(mdpll->dpll, &mlx5_dpll_device_ops, mdpll);
>-      dpll_device_put(mdpll->dpll, NULL);
>+      dpll_device_put(mdpll->dpll, &mdpll->dpll_tracker);
>       kfree(mdpll);
>
>       mlx5_dpll_synce_status_set(mdev,
>diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
>index f39b3966b3e8c..1b16a9c3d7fdc 100644
>--- a/drivers/ptp/ptp_ocp.c
>+++ b/drivers/ptp/ptp_ocp.c
>@@ -285,6 +285,7 @@ struct ptp_ocp_sma_connector {
>       u8      default_fcn;
>       struct dpll_pin            *dpll_pin;
>       struct dpll_pin_properties dpll_prop;
>+      dpll_tracker               tracker;
> };
>
> struct ocp_attr_group {
>@@ -383,6 +384,7 @@ struct ptp_ocp {
>       struct ptp_ocp_sma_connector sma[OCP_SMA_NUM];
>       const struct ocp_sma_op *sma_op;
>       struct dpll_device *dpll;
>+      dpll_tracker tracker;
>       int signals_nr;
>       int freq_in_nr;
> };
>@@ -4788,7 +4790,7 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct
>pci_device_id *id)
>       devlink_register(devlink);
>
>       clkid = pci_get_dsn(pdev);
>-      bp->dpll = dpll_device_get(clkid, 0, THIS_MODULE, NULL);
>+      bp->dpll = dpll_device_get(clkid, 0, THIS_MODULE, &bp->tracker);
>       if (IS_ERR(bp->dpll)) {
>               err = PTR_ERR(bp->dpll);
>               dev_err(&pdev->dev, "dpll_device_alloc failed\n");
>@@ -4801,7 +4803,8 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct
>pci_device_id *id)
>
>       for (i = 0; i < OCP_SMA_NUM; i++) {
>               bp->sma[i].dpll_pin = dpll_pin_get(clkid, i, THIS_MODULE,
>-                                                 &bp->sma[i].dpll_prop, NULL);
>+                                                 &bp->sma[i].dpll_prop,
>+                                                 &bp->sma[i].tracker);
>               if (IS_ERR(bp->sma[i].dpll_pin)) {
>                       err = PTR_ERR(bp->sma[i].dpll_pin);
>                       goto out_dpll;
>@@ -4810,7 +4813,7 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct
>pci_device_id *id)
>               err = dpll_pin_register(bp->dpll, bp->sma[i].dpll_pin,
>&dpll_pins_ops,
>                                       &bp->sma[i]);
>               if (err) {
>-                      dpll_pin_put(bp->sma[i].dpll_pin, NULL);
>+                      dpll_pin_put(bp->sma[i].dpll_pin, &bp->sma[i].tracker);
>                       goto out_dpll;
>               }
>       }
>@@ -4820,9 +4823,9 @@ ptp_ocp_probe(struct pci_dev *pdev, const struct
>pci_device_id *id)
> out_dpll:
>       while (i--) {
>               dpll_pin_unregister(bp->dpll, bp->sma[i].dpll_pin,
>&dpll_pins_ops, &bp->sma[i]);
>-              dpll_pin_put(bp->sma[i].dpll_pin, NULL);
>+              dpll_pin_put(bp->sma[i].dpll_pin, &bp->sma[i].tracker);
>       }
>-      dpll_device_put(bp->dpll, NULL);
>+      dpll_device_put(bp->dpll, &bp->tracker);
> out:
>       ptp_ocp_detach(bp);
> out_disable:
>@@ -4843,11 +4846,11 @@ ptp_ocp_remove(struct pci_dev *pdev)
>       for (i = 0; i < OCP_SMA_NUM; i++) {
>               if (bp->sma[i].dpll_pin) {
>                       dpll_pin_unregister(bp->dpll, bp->sma[i].dpll_pin,
>&dpll_pins_ops, &bp->sma[i]);
>-                      dpll_pin_put(bp->sma[i].dpll_pin, NULL);
>+                      dpll_pin_put(bp->sma[i].dpll_pin, &bp->sma[i].tracker);
>               }
>       }
>       dpll_device_unregister(bp->dpll, &dpll_ops, bp);
>-      dpll_device_put(bp->dpll, NULL);
>+      dpll_device_put(bp->dpll, &bp->tracker);
>       devlink_unregister(devlink);
>       ptp_ocp_detach(bp);
>       pci_disable_device(pdev);
>--
>2.52.0

Reply via email to