All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH mlx5-next 0/2] Improvements for PTP clock in mlx5 driver
@ 2018-12-03 12:59 Miroslav Lichvar
  2018-12-03 12:59 ` [PATCH mlx5-next 1/2] mlx5: update timecounter at least twice per counter overflow Miroslav Lichvar
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Miroslav Lichvar @ 2018-12-03 12:59 UTC (permalink / raw)
  To: Saeed Mahameed; +Cc: netdev, Richard Cochran, Hangbin Liu, Miroslav Lichvar

This is a pair of patches for the mlx5 driver related to the PTP clock.

The first patch fixes a potential issue causing backward jumps due to a
late update of the PHC timecounter.

The second patch adds support for the PTP_SYS_OFFSET_EXTENDED ioctl.

Miroslav Lichvar (2):
  mlx5: update timecounter at least twice per counter overflow
  mlx5: extend PTP gettime function to read system clock

 .../ethernet/mellanox/mlx5/core/lib/clock.c   | 24 +++++++++++--------
 .../net/ethernet/mellanox/mlx5/core/main.c    | 11 +++++++--
 .../ethernet/mellanox/mlx5/core/mlx5_core.h   |  4 +++-
 3 files changed, 26 insertions(+), 13 deletions(-)

-- 
2.17.2

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH mlx5-next 1/2] mlx5: update timecounter at least twice per counter overflow
  2018-12-03 12:59 [PATCH mlx5-next 0/2] Improvements for PTP clock in mlx5 driver Miroslav Lichvar
@ 2018-12-03 12:59 ` Miroslav Lichvar
  2018-12-03 12:59 ` [PATCH mlx5-next 2/2] mlx5: extend PTP gettime function to read system clock Miroslav Lichvar
  2018-12-12  3:41 ` [PATCH mlx5-next 0/2] Improvements for PTP clock in mlx5 driver Saeed Mahameed
  2 siblings, 0 replies; 5+ messages in thread
From: Miroslav Lichvar @ 2018-12-03 12:59 UTC (permalink / raw)
  To: Saeed Mahameed
  Cc: netdev, Richard Cochran, Hangbin Liu, Miroslav Lichvar, Ariel Levkovich

The timecounter needs to be updated at least once in half of the
cyclecounter interval to prevent timecounter_cyc2time() interpreting a
new timestamp as an old value and causing a backward jump.

This would be an issue if the timecounter multiplier was so small that
the update interval would not be limited by the 64-bit overflow in
multiplication.

Shorten the calculated interval to make sure the timecounter is updated
in time even when the system clock is slowed down by up to 10%, the
multiplier is increased by up to 10%, and the scheduled overflow check
is late by 15%.

Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Ariel Levkovich <lariel@mellanox.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index 0d90b1b4a3d3..2d6168ee99e8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -511,14 +511,14 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
 			 ktime_to_ns(ktime_get_real()));
 
 	/* Calculate period in seconds to call the overflow watchdog - to make
-	 * sure counter is checked at least once every wrap around.
+	 * sure counter is checked at least twice every wrap around.
 	 * The period is calculated as the minimum between max HW cycles count
 	 * (The clock source mask) and max amount of cycles that can be
 	 * multiplied by clock multiplier where the result doesn't exceed
 	 * 64bits.
 	 */
 	overflow_cycles = div64_u64(~0ULL >> 1, clock->cycles.mult);
-	overflow_cycles = min(overflow_cycles, clock->cycles.mask >> 1);
+	overflow_cycles = min(overflow_cycles, div_u64(clock->cycles.mask, 3));
 
 	ns = cyclecounter_cyc2ns(&clock->cycles, overflow_cycles,
 				 frac, &frac);
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH mlx5-next 2/2] mlx5: extend PTP gettime function to read system clock
  2018-12-03 12:59 [PATCH mlx5-next 0/2] Improvements for PTP clock in mlx5 driver Miroslav Lichvar
  2018-12-03 12:59 ` [PATCH mlx5-next 1/2] mlx5: update timecounter at least twice per counter overflow Miroslav Lichvar
@ 2018-12-03 12:59 ` Miroslav Lichvar
  2018-12-05  1:25   ` Saeed Mahameed
  2018-12-12  3:41 ` [PATCH mlx5-next 0/2] Improvements for PTP clock in mlx5 driver Saeed Mahameed
  2 siblings, 1 reply; 5+ messages in thread
From: Miroslav Lichvar @ 2018-12-03 12:59 UTC (permalink / raw)
  To: Saeed Mahameed; +Cc: netdev, Richard Cochran, Hangbin Liu, Miroslav Lichvar

Read the system time right before and immediately after reading the low
register of the internal timer. This adds support for the
PTP_SYS_OFFSET_EXTENDED ioctl.

Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
---
 .../ethernet/mellanox/mlx5/core/lib/clock.c   | 20 +++++++++++--------
 .../net/ethernet/mellanox/mlx5/core/main.c    | 11 ++++++++--
 .../ethernet/mellanox/mlx5/core/mlx5_core.h   |  4 +++-
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
index 2d6168ee99e8..f9618047c16a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -71,7 +71,7 @@ static u64 read_internal_timer(const struct cyclecounter *cc)
 	struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev,
 						  clock);
 
-	return mlx5_read_internal_timer(mdev) & cc->mask;
+	return mlx5_read_internal_timer(mdev, NULL) & cc->mask;
 }
 
 static void mlx5_update_clock_info_page(struct mlx5_core_dev *mdev)
@@ -155,15 +155,19 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp,
 	return 0;
 }
 
-static int mlx5_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
+static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts,
+			     struct ptp_system_timestamp *sts)
 {
 	struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock,
 						ptp_info);
-	u64 ns;
+	struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev,
+						  clock);
 	unsigned long flags;
+	u64 cycles, ns;
 
 	write_seqlock_irqsave(&clock->lock, flags);
-	ns = timecounter_read(&clock->tc);
+	cycles = mlx5_read_internal_timer(mdev, sts);
+	ns = timecounter_cyc2time(&clock->tc, cycles);
 	write_sequnlock_irqrestore(&clock->lock, flags);
 
 	*ts = ns_to_timespec64(ns);
@@ -306,7 +310,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
 		ts.tv_sec = rq->perout.start.sec;
 		ts.tv_nsec = rq->perout.start.nsec;
 		ns = timespec64_to_ns(&ts);
-		cycles_now = mlx5_read_internal_timer(mdev);
+		cycles_now = mlx5_read_internal_timer(mdev, NULL);
 		write_seqlock_irqsave(&clock->lock, flags);
 		nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
 		nsec_delta = ns - nsec_now;
@@ -383,7 +387,7 @@ static const struct ptp_clock_info mlx5_ptp_clock_info = {
 	.pps		= 0,
 	.adjfreq	= mlx5_ptp_adjfreq,
 	.adjtime	= mlx5_ptp_adjtime,
-	.gettime64	= mlx5_ptp_gettime,
+	.gettimex64	= mlx5_ptp_gettimex,
 	.settime64	= mlx5_ptp_settime,
 	.enable		= NULL,
 	.verify		= NULL,
@@ -466,8 +470,8 @@ void mlx5_pps_event(struct mlx5_core_dev *mdev,
 		ptp_clock_event(clock->ptp, &ptp_event);
 		break;
 	case PTP_PF_PEROUT:
-		mlx5_ptp_gettime(&clock->ptp_info, &ts);
-		cycles_now = mlx5_read_internal_timer(mdev);
+		mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL);
+		cycles_now = mlx5_read_internal_timer(mdev, NULL);
 		ts.tv_sec += 1;
 		ts.tv_nsec = 0;
 		ns = timespec64_to_ns(&ts);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 28132c7dc05f..6f1cf291df7e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -624,15 +624,22 @@ int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id)
 	return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
-u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev)
+u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev,
+			     struct ptp_system_timestamp *sts)
 {
 	u32 timer_h, timer_h1, timer_l;
 
 	timer_h = ioread32be(&dev->iseg->internal_timer_h);
+	ptp_read_system_prets(sts);
 	timer_l = ioread32be(&dev->iseg->internal_timer_l);
+	ptp_read_system_postts(sts);
 	timer_h1 = ioread32be(&dev->iseg->internal_timer_h);
-	if (timer_h != timer_h1) /* wrap around */
+	if (timer_h != timer_h1) {
+		/* wrap around */
+		ptp_read_system_prets(sts);
 		timer_l = ioread32be(&dev->iseg->internal_timer_l);
+		ptp_read_system_postts(sts);
+	}
 
 	return (u64)timer_l | (u64)timer_h1 << 32;
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 0594d0961cb3..3d66afc9b7a5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -38,6 +38,7 @@
 #include <linux/sched.h>
 #include <linux/if_link.h>
 #include <linux/firmware.h>
+#include <linux/ptp_clock_kernel.h>
 #include <linux/mlx5/cq.h>
 #include <linux/mlx5/fs.h>
 
@@ -122,7 +123,8 @@ int mlx5_modify_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
 int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev, u8 hierarchy,
 					u32 element_id);
 int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev);
-u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev);
+u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev,
+			     struct ptp_system_timestamp *sts);
 
 int mlx5_eq_init(struct mlx5_core_dev *dev);
 void mlx5_eq_cleanup(struct mlx5_core_dev *dev);
-- 
2.17.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH mlx5-next 2/2] mlx5: extend PTP gettime function to read system clock
  2018-12-03 12:59 ` [PATCH mlx5-next 2/2] mlx5: extend PTP gettime function to read system clock Miroslav Lichvar
@ 2018-12-05  1:25   ` Saeed Mahameed
  0 siblings, 0 replies; 5+ messages in thread
From: Saeed Mahameed @ 2018-12-05  1:25 UTC (permalink / raw)
  To: mlichvar; +Cc: netdev, haliu, richardcochran

On Mon, 2018-12-03 at 13:59 +0100, Miroslav Lichvar wrote:
> Read the system time right before and immediately after reading the
> low
> register of the internal timer. This adds support for the
> PTP_SYS_OFFSET_EXTENDED ioctl.
> 
> Cc: Richard Cochran <richardcochran@gmail.com>
> Cc: Saeed Mahameed <saeedm@mellanox.com>
> Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>


Hi Miroslav, 

the two patches look good to me,  i am waiting for Ariel's feedback on
the first patch and then i am going to merge them to mlx5-next branch
then send them later to netdev (net-next).


> ---
>  .../ethernet/mellanox/mlx5/core/lib/clock.c   | 20 +++++++++++----
> ----
>  .../net/ethernet/mellanox/mlx5/core/main.c    | 11 ++++++++--
>  .../ethernet/mellanox/mlx5/core/mlx5_core.h   |  4 +++-
>  3 files changed, 24 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
> b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
> index 2d6168ee99e8..f9618047c16a 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
> @@ -71,7 +71,7 @@ static u64 read_internal_timer(const struct
> cyclecounter *cc)
>  	struct mlx5_core_dev *mdev = container_of(clock, struct
> mlx5_core_dev,
>  						  clock);
>  
> -	return mlx5_read_internal_timer(mdev) & cc->mask;
> +	return mlx5_read_internal_timer(mdev, NULL) & cc->mask;
>  }
>  
>  static void mlx5_update_clock_info_page(struct mlx5_core_dev *mdev)
> @@ -155,15 +155,19 @@ static int mlx5_ptp_settime(struct
> ptp_clock_info *ptp,
>  	return 0;
>  }
>  
> -static int mlx5_ptp_gettime(struct ptp_clock_info *ptp, struct
> timespec64 *ts)
> +static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct
> timespec64 *ts,
> +			     struct ptp_system_timestamp *sts)
>  {
>  	struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock,
>  						ptp_info);
> -	u64 ns;
> +	struct mlx5_core_dev *mdev = container_of(clock, struct
> mlx5_core_dev,
> +						  clock);
>  	unsigned long flags;
> +	u64 cycles, ns;
>  
>  	write_seqlock_irqsave(&clock->lock, flags);
> -	ns = timecounter_read(&clock->tc);
> +	cycles = mlx5_read_internal_timer(mdev, sts);
> +	ns = timecounter_cyc2time(&clock->tc, cycles);
>  	write_sequnlock_irqrestore(&clock->lock, flags);
>  
>  	*ts = ns_to_timespec64(ns);
> @@ -306,7 +310,7 @@ static int mlx5_perout_configure(struct
> ptp_clock_info *ptp,
>  		ts.tv_sec = rq->perout.start.sec;
>  		ts.tv_nsec = rq->perout.start.nsec;
>  		ns = timespec64_to_ns(&ts);
> -		cycles_now = mlx5_read_internal_timer(mdev);
> +		cycles_now = mlx5_read_internal_timer(mdev, NULL);
>  		write_seqlock_irqsave(&clock->lock, flags);
>  		nsec_now = timecounter_cyc2time(&clock->tc,
> cycles_now);
>  		nsec_delta = ns - nsec_now;
> @@ -383,7 +387,7 @@ static const struct ptp_clock_info
> mlx5_ptp_clock_info = {
>  	.pps		= 0,
>  	.adjfreq	= mlx5_ptp_adjfreq,
>  	.adjtime	= mlx5_ptp_adjtime,
> -	.gettime64	= mlx5_ptp_gettime,
> +	.gettimex64	= mlx5_ptp_gettimex,
>  	.settime64	= mlx5_ptp_settime,
>  	.enable		= NULL,
>  	.verify		= NULL,
> @@ -466,8 +470,8 @@ void mlx5_pps_event(struct mlx5_core_dev *mdev,
>  		ptp_clock_event(clock->ptp, &ptp_event);
>  		break;
>  	case PTP_PF_PEROUT:
> -		mlx5_ptp_gettime(&clock->ptp_info, &ts);
> -		cycles_now = mlx5_read_internal_timer(mdev);
> +		mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL);
> +		cycles_now = mlx5_read_internal_timer(mdev, NULL);
>  		ts.tv_sec += 1;
>  		ts.tv_nsec = 0;
>  		ns = timespec64_to_ns(&ts);
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c
> b/drivers/net/ethernet/mellanox/mlx5/core/main.c
> index 28132c7dc05f..6f1cf291df7e 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
> @@ -624,15 +624,22 @@ int mlx5_core_disable_hca(struct mlx5_core_dev
> *dev, u16 func_id)
>  	return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
>  }
>  
> -u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev)
> +u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev,
> +			     struct ptp_system_timestamp *sts)
>  {
>  	u32 timer_h, timer_h1, timer_l;
>  
>  	timer_h = ioread32be(&dev->iseg->internal_timer_h);
> +	ptp_read_system_prets(sts);
>  	timer_l = ioread32be(&dev->iseg->internal_timer_l);
> +	ptp_read_system_postts(sts);
>  	timer_h1 = ioread32be(&dev->iseg->internal_timer_h);
> -	if (timer_h != timer_h1) /* wrap around */
> +	if (timer_h != timer_h1) {
> +		/* wrap around */
> +		ptp_read_system_prets(sts);
>  		timer_l = ioread32be(&dev->iseg->internal_timer_l);
> +		ptp_read_system_postts(sts);
> +	}
>  
>  	return (u64)timer_l | (u64)timer_h1 << 32;
>  }
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
> b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
> index 0594d0961cb3..3d66afc9b7a5 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
> @@ -38,6 +38,7 @@
>  #include <linux/sched.h>
>  #include <linux/if_link.h>
>  #include <linux/firmware.h>
> +#include <linux/ptp_clock_kernel.h>
>  #include <linux/mlx5/cq.h>
>  #include <linux/mlx5/fs.h>
>  
> @@ -122,7 +123,8 @@ int mlx5_modify_scheduling_element_cmd(struct
> mlx5_core_dev *dev, u8 hierarchy,
>  int mlx5_destroy_scheduling_element_cmd(struct mlx5_core_dev *dev,
> u8 hierarchy,
>  					u32 element_id);
>  int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev);
> -u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev);
> +u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev,
> +			     struct ptp_system_timestamp *sts);
>  
>  int mlx5_eq_init(struct mlx5_core_dev *dev);
>  void mlx5_eq_cleanup(struct mlx5_core_dev *dev);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH mlx5-next 0/2] Improvements for PTP clock in mlx5 driver
  2018-12-03 12:59 [PATCH mlx5-next 0/2] Improvements for PTP clock in mlx5 driver Miroslav Lichvar
  2018-12-03 12:59 ` [PATCH mlx5-next 1/2] mlx5: update timecounter at least twice per counter overflow Miroslav Lichvar
  2018-12-03 12:59 ` [PATCH mlx5-next 2/2] mlx5: extend PTP gettime function to read system clock Miroslav Lichvar
@ 2018-12-12  3:41 ` Saeed Mahameed
  2 siblings, 0 replies; 5+ messages in thread
From: Saeed Mahameed @ 2018-12-12  3:41 UTC (permalink / raw)
  To: mlichvar; +Cc: Saeed Mahameed, Linux Netdev List, Richard Cochran, haliu

On Mon, Dec 3, 2018 at 4:59 AM Miroslav Lichvar <mlichvar@redhat.com> wrote:
>
> This is a pair of patches for the mlx5 driver related to the PTP clock.
>
> The first patch fixes a potential issue causing backward jumps due to a
> late update of the PHC timecounter.
>
> The second patch adds support for the PTP_SYS_OFFSET_EXTENDED ioctl.
>
> Miroslav Lichvar (2):
>   mlx5: update timecounter at least twice per counter overflow
>   mlx5: extend PTP gettime function to read system clock

Applied to mlx5-next, will be sent to net-next soon.

Thanks!

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-12-12  3:41 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-03 12:59 [PATCH mlx5-next 0/2] Improvements for PTP clock in mlx5 driver Miroslav Lichvar
2018-12-03 12:59 ` [PATCH mlx5-next 1/2] mlx5: update timecounter at least twice per counter overflow Miroslav Lichvar
2018-12-03 12:59 ` [PATCH mlx5-next 2/2] mlx5: extend PTP gettime function to read system clock Miroslav Lichvar
2018-12-05  1:25   ` Saeed Mahameed
2018-12-12  3:41 ` [PATCH mlx5-next 0/2] Improvements for PTP clock in mlx5 driver Saeed Mahameed

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.