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.

net/mlx5: use do_aux_work for PHC overflow checks

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>

authored by

Vadim Fedorenko and committed by
Paolo Abeni
e61e6c41 e62de010

+13 -12
+13 -11
drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
··· 322 322 } 323 323 } 324 324 325 - static void mlx5_timestamp_overflow(struct work_struct *work) 325 + static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info) 326 326 { 327 - struct delayed_work *dwork = to_delayed_work(work); 328 327 struct mlx5_core_dev *mdev; 329 328 struct mlx5_timer *timer; 330 329 struct mlx5_clock *clock; 331 330 unsigned long flags; 332 331 333 - timer = container_of(dwork, struct mlx5_timer, overflow_work); 334 - clock = container_of(timer, struct mlx5_clock, timer); 332 + clock = container_of(ptp_info, struct mlx5_clock, ptp_info); 335 333 mdev = container_of(clock, struct mlx5_core_dev, clock); 334 + timer = &clock->timer; 336 335 337 336 if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) 338 337 goto out; ··· 342 343 write_sequnlock_irqrestore(&clock->lock, flags); 343 344 344 345 out: 345 - schedule_delayed_work(&timer->overflow_work, timer->overflow_period); 346 + return timer->overflow_period; 346 347 } 347 348 348 349 static int mlx5_ptp_settime_real_time(struct mlx5_core_dev *mdev, ··· 516 517 timer->cycles.mult = mult; 517 518 mlx5_update_clock_info_page(mdev); 518 519 write_sequnlock_irqrestore(&clock->lock, flags); 520 + ptp_schedule_worker(clock->ptp, timer->overflow_period); 519 521 520 522 return 0; 521 523 } ··· 852 852 .settime64 = mlx5_ptp_settime, 853 853 .enable = NULL, 854 854 .verify = NULL, 855 + .do_aux_work = mlx5_timestamp_overflow, 855 856 }; 856 857 857 858 static int mlx5_query_mtpps_pin_mode(struct mlx5_core_dev *mdev, u8 pin, ··· 1053 1052 do_div(ns, NSEC_PER_SEC / HZ); 1054 1053 timer->overflow_period = ns; 1055 1054 1056 - INIT_DELAYED_WORK(&timer->overflow_work, mlx5_timestamp_overflow); 1057 - if (timer->overflow_period) 1058 - schedule_delayed_work(&timer->overflow_work, 0); 1059 - else 1055 + if (!timer->overflow_period) { 1056 + timer->overflow_period = HZ; 1060 1057 mlx5_core_warn(mdev, 1061 - "invalid overflow period, overflow_work is not scheduled\n"); 1058 + "invalid overflow period, overflow_work is scheduled once per second\n"); 1059 + } 1062 1060 1063 1061 if (clock_info) 1064 1062 clock_info->overflow_period = timer->overflow_period; ··· 1172 1172 1173 1173 MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT); 1174 1174 mlx5_eq_notifier_register(mdev, &clock->pps_nb); 1175 + 1176 + if (clock->ptp) 1177 + ptp_schedule_worker(clock->ptp, 0); 1175 1178 } 1176 1179 1177 1180 void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) ··· 1191 1188 } 1192 1189 1193 1190 cancel_work_sync(&clock->pps_info.out_work); 1194 - cancel_delayed_work_sync(&clock->timer.overflow_work); 1195 1191 1196 1192 if (mdev->clock_info) { 1197 1193 free_page((unsigned long)mdev->clock_info);
-1
include/linux/mlx5/driver.h
··· 691 691 struct timecounter tc; 692 692 u32 nominal_c_mult; 693 693 unsigned long overflow_period; 694 - struct delayed_work overflow_work; 695 694 }; 696 695 697 696 struct mlx5_clock {