]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net/mlx5: use do_aux_work for PHC overflow checks
authorVadim Fedorenko <vadfed@meta.com>
Tue, 7 Jan 2025 10:48:12 +0000 (02:48 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 13 Mar 2025 11:47:02 +0000 (12:47 +0100)
[ Upstream commit e61e6c415ba9ff2b32bb6780ce1b17d1d76238f1 ]

The overflow_work is using system wq to do overflow checks and updates
for PHC device timecounter, which might be overhelmed by other tasks.
But there is dedicated kthread in PTP subsystem designed for such
things. This patch changes the work queue to proper align with PTP
subsystem and to avoid overloading system work queue.
The adjfine() function acts the same way as overflow check worker,
we can postpone ptp aux worker till the next overflow period after
adjfine() was called.

Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
Acked-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20250107104812.380225-1-vadfed@meta.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
include/linux/mlx5/driver.h

index 80dee8c692495acd4e87578d6293d000c9629a9c..3d0029fb5b57995c1531b753f7cac1d29190f33b 100644 (file)
@@ -150,17 +150,16 @@ static void mlx5_pps_out(struct work_struct *work)
        }
 }
 
-static void mlx5_timestamp_overflow(struct work_struct *work)
+static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info)
 {
-       struct delayed_work *dwork = to_delayed_work(work);
        struct mlx5_core_dev *mdev;
        struct mlx5_timer *timer;
        struct mlx5_clock *clock;
        unsigned long flags;
 
-       timer = container_of(dwork, struct mlx5_timer, overflow_work);
-       clock = container_of(timer, struct mlx5_clock, timer);
+       clock = container_of(ptp_info, struct mlx5_clock, ptp_info);
        mdev = container_of(clock, struct mlx5_core_dev, clock);
+       timer = &clock->timer;
 
        if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
                goto out;
@@ -171,7 +170,7 @@ static void mlx5_timestamp_overflow(struct work_struct *work)
        write_sequnlock_irqrestore(&clock->lock, flags);
 
 out:
-       schedule_delayed_work(&timer->overflow_work, timer->overflow_period);
+       return timer->overflow_period;
 }
 
 static int mlx5_ptp_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts)
@@ -253,6 +252,7 @@ static int mlx5_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
                                       timer->nominal_c_mult + diff;
        mlx5_update_clock_info_page(mdev);
        write_sequnlock_irqrestore(&clock->lock, flags);
+       ptp_schedule_worker(clock->ptp, timer->overflow_period);
 
        return 0;
 }
@@ -467,6 +467,7 @@ static const struct ptp_clock_info mlx5_ptp_clock_info = {
        .settime64      = mlx5_ptp_settime,
        .enable         = NULL,
        .verify         = NULL,
+       .do_aux_work    = mlx5_timestamp_overflow,
 };
 
 static int mlx5_query_mtpps_pin_mode(struct mlx5_core_dev *mdev, u8 pin,
@@ -649,12 +650,11 @@ static void mlx5_init_overflow_period(struct mlx5_clock *clock)
        do_div(ns, NSEC_PER_SEC / HZ);
        timer->overflow_period = ns;
 
-       INIT_DELAYED_WORK(&timer->overflow_work, mlx5_timestamp_overflow);
-       if (timer->overflow_period)
-               schedule_delayed_work(&timer->overflow_work, 0);
-       else
+       if (!timer->overflow_period) {
+               timer->overflow_period = HZ;
                mlx5_core_warn(mdev,
-                              "invalid overflow period, overflow_work is not scheduled\n");
+                              "invalid overflow period, overflow_work is scheduled once per second\n");
+       }
 
        if (clock_info)
                clock_info->overflow_period = timer->overflow_period;
@@ -718,6 +718,9 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
 
        MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT);
        mlx5_eq_notifier_register(mdev, &clock->pps_nb);
+
+       if (clock->ptp)
+               ptp_schedule_worker(clock->ptp, 0);
 }
 
 void mlx5_cleanup_clock(struct mlx5_core_dev *mdev)
@@ -734,7 +737,6 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev)
        }
 
        cancel_work_sync(&clock->pps_info.out_work);
-       cancel_delayed_work_sync(&clock->timer.overflow_work);
 
        if (mdev->clock_info) {
                free_page((unsigned long)mdev->clock_info);
index 68a12caf5eb1636b319bf32945e9728b4d68e905..56cb2fbc496e65d5548f8d3a2fa33351fe3c42fb 100644 (file)
@@ -651,7 +651,6 @@ struct mlx5_timer {
        struct timecounter         tc;
        u32                        nominal_c_mult;
        unsigned long              overflow_period;
-       struct delayed_work        overflow_work;
 };
 
 struct mlx5_clock {