Message ID | 1366631767-16493-6-git-send-email-amirv@mellanox.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
On Mon, 2013-04-22 at 14:56 +0300, Amir Vadai wrote: > Add a service task to run tasks that needed to be executed periodically. > Currently the only task is a watchdog to catch NIC clock overflow, to make > timestamping accurate. > Will move the statistics task into this framework in a later patch. > > Signed-off-by: Amir Vadai <amirv@mellanox.com> > --- > drivers/net/ethernet/mellanox/mlx4/en_clock.c | 20 ++++++++++++++++++++ > drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 24 ++++++++++++++++++++++++ > drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 4 ++++ > 3 files changed, 48 insertions(+), 0 deletions(-) > > diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c > index 6d8227d..c1982a4 100644 > --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c > +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c > @@ -126,4 +126,24 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) > > timecounter_init(&mdev->clock, &mdev->cycles, > ktime_to_ns(ktime_get_real())); > + > + /* Calculate period in seconds to call the overflow watchdog. Doing > + * that, by dividing the maximal cycles value in nano-seconds, convert > + * it to seconds, and divide by 2 - to make sure counter is checked at > + * least once every wrap around. > + */ > + mdev->overflow_period = > + cyclecounter_cyc2ns(&mdev->cycles, > + mdev->cycles.mask) / 1000000 / 2; > +} > + So this 1000000 looks like NSEC_PER_SEC/HZ ? What if HZ=100 ? -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 22/04/2013 22:01, Eric Dumazet wrote: > On Mon, 2013-04-22 at 14:56 +0300, Amir Vadai wrote: >> Add a service task to run tasks that needed to be executed periodically. >> Currently the only task is a watchdog to catch NIC clock overflow, to make >> timestamping accurate. >> Will move the statistics task into this framework in a later patch. >> >> Signed-off-by: Amir Vadai <amirv@mellanox.com> >> --- >> drivers/net/ethernet/mellanox/mlx4/en_clock.c | 20 ++++++++++++++++++++ >> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 24 ++++++++++++++++++++++++ >> drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 4 ++++ >> 3 files changed, 48 insertions(+), 0 deletions(-) >> >> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c >> index 6d8227d..c1982a4 100644 >> --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c >> +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c >> @@ -126,4 +126,24 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) >> >> timecounter_init(&mdev->clock, &mdev->cycles, >> ktime_to_ns(ktime_get_real())); >> + >> + /* Calculate period in seconds to call the overflow watchdog. Doing >> + * that, by dividing the maximal cycles value in nano-seconds, convert >> + * it to seconds, and divide by 2 - to make sure counter is checked at >> + * least once every wrap around. >> + */ >> + mdev->overflow_period = >> + cyclecounter_cyc2ns(&mdev->cycles, >> + mdev->cycles.mask) / 1000000 / 2; >> +} >> + > > So this 1000000 looks like NSEC_PER_SEC/HZ ? No. It is just a typo - used 10^6 instead of 10^9 for nano's. But it is a good idea to have the HZ multiplied in the initialization of overflow_period - will fix the calculation and change overflow_period units to be jiffies, and not seconds. > > What if HZ=100 ? > > > Thanks, Amir -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 6d8227d..c1982a4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -126,4 +126,24 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) timecounter_init(&mdev->clock, &mdev->cycles, ktime_to_ns(ktime_get_real())); + + /* Calculate period in seconds to call the overflow watchdog. Doing + * that, by dividing the maximal cycles value in nano-seconds, convert + * it to seconds, and divide by 2 - to make sure counter is checked at + * least once every wrap around. + */ + mdev->overflow_period = + cyclecounter_cyc2ns(&mdev->cycles, + mdev->cycles.mask) / 1000000 / 2; +} + +void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev) +{ + bool timeout = time_is_before_jiffies(mdev->last_overflow_check + + HZ * mdev->overflow_period); + + if (timeout) { + timecounter_read(&mdev->clock); + mdev->last_overflow_check = jiffies; + } } diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 4cb9f32..f4f88b8 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1361,6 +1361,26 @@ static void mlx4_en_do_get_stats(struct work_struct *work) mutex_unlock(&mdev->state_lock); } +/* mlx4_en_service_task - Run service task for tasks that needed to be done + * periodically + */ +static void mlx4_en_service_task(struct work_struct *work) +{ + struct delayed_work *delay = to_delayed_work(work); + struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv, + service_task); + struct mlx4_en_dev *mdev = priv->mdev; + + mutex_lock(&mdev->state_lock); + if (mdev->device_up) { + mlx4_en_ptp_overflow_check(mdev); + + queue_delayed_work(mdev->workqueue, &priv->service_task, + SERVICE_TASK_DELAY); + } + mutex_unlock(&mdev->state_lock); +} + static void mlx4_en_linkstate(struct work_struct *work) { struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, @@ -1865,6 +1885,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev) mlx4_free_hwq_res(mdev->dev, &priv->res, MLX4_EN_PAGE_SIZE); cancel_delayed_work(&priv->stats_task); + cancel_delayed_work(&priv->service_task); /* flush any pending task for this netdev */ flush_workqueue(mdev->workqueue); @@ -2084,6 +2105,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, INIT_WORK(&priv->watchdog_task, mlx4_en_restart); INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); + INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task); #ifdef CONFIG_MLX4_EN_DCB if (!mlx4_is_slave(priv->mdev->dev)) { if (mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_SET_ETH_SCHED) { @@ -2206,6 +2228,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, } mlx4_en_set_default_moderation(priv); queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); + queue_delayed_work(mdev->workqueue, &priv->service_task, + SERVICE_TASK_DELAY); return 0; out: diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 85b0754..f4b61c5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -78,6 +78,7 @@ #define STAMP_SHIFT 31 #define STAMP_VAL 0x7fffffff #define STATS_DELAY (HZ / 4) +#define SERVICE_TASK_DELAY (HZ / 4) #define MAX_NUM_OF_FS_RULES 256 #define MLX4_EN_FILTER_HASH_SHIFT 4 @@ -355,6 +356,7 @@ struct mlx4_en_dev { struct cyclecounter cycles; struct timecounter clock; unsigned long last_overflow_check; + u32 overflow_period; }; @@ -519,6 +521,7 @@ struct mlx4_en_priv { struct work_struct watchdog_task; struct work_struct linkstate_task; struct delayed_work stats_task; + struct delayed_work service_task; struct mlx4_en_perf_stats pstats; struct mlx4_en_pkt_stats pkstats; struct mlx4_en_port_stats port_stats; @@ -645,6 +648,7 @@ void mlx4_en_cleanup_filters(struct mlx4_en_priv *priv, #define MLX4_EN_NUM_SELF_TEST 5 void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf); u64 mlx4_en_mac_to_u64(u8 *addr); +void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev); /* * Functions for time stamping
Add a service task to run tasks that needed to be executed periodically. Currently the only task is a watchdog to catch NIC clock overflow, to make timestamping accurate. Will move the statistics task into this framework in a later patch. Signed-off-by: Amir Vadai <amirv@mellanox.com> --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 20 ++++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 24 ++++++++++++++++++++++++ drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 4 ++++ 3 files changed, 48 insertions(+), 0 deletions(-)