Re: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-29 Thread Paul Bolle
On ma, 2015-07-27 at 17:46 -0700, Christopher Hall wrote:
> --- /dev/null
> +++ b/arch/x86/include/asm/art.h

> +#ifndef CONFIG_X86_ART
> +
> +static inline int setup_art(void)
> +{
> + return 0;
> +}
> +
> +static inline bool has_art(void)
> +{
> + return false;
> +}
> +
> +static inline int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
> +{
> + return -ENXIO;
> +}
> +static inline int art_to_realtime64(struct timespec64 *realtime, cycle_t art)
> +{
> + return -ENXIO;
> +}
> +static inline int art_to_mono64(struct timespec64 *mono, cycle_t art)
> +{
> + return -ENXIO;
> +}
> +
> +#else
> +
> +extern int setup_art(void);
> +extern bool has_art(void);
> +extern int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art);
> +extern int art_to_realtime64(struct timespec64 *realtime, cycle_t art);
> +extern int art_to_mono64(struct timespec64 *mono, cycle_t art);
> +
> +#endif

> --- /dev/null
> +++ b/arch/x86/kernel/art.c

> +static bool has_art(void)
> +{
> + return art_present;
> +}
> +EXPORT_SYMBOL(has_art);

This exports a static function. Does that work?

> +static int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
> +{
> + if (!checked_art_to_tsc())
> + return -ENXIO;
> + return tsc_to_rawmono64(rawmono, art);
> +}
> +EXPORT_SYMBOL(art_to_rawmono64);
> +
> +static int art_to_realtime64(struct timespec64 *realtime, cycle_t art)
> +{
> + if (!checked_art_to_tsc())
> + return -ENXIO;
> + return tsc_to_realtime64(realtime, art);
> +}
> +EXPORT_SYMBOL(art_to_realtime64);
> +
> +static int art_to_mono64(struct timespec64 *mono, cycle_t art)
> +{
> + if (!checked_art_to_tsc())
> + return -ENXIO;
> + return tsc_to_mono64(mono, art);
> +}
> +EXPORT_SYMBOL(art_to_mono64);

Ditto (three times).

By the way, this series doesn't add users for art_to_mono64() and
art_to_mono64(), right?

Thanks,


Paul Bolle
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-29 Thread Paul Bolle
On ma, 2015-07-27 at 17:46 -0700, Christopher Hall wrote:
 --- /dev/null
 +++ b/arch/x86/include/asm/art.h

 +#ifndef CONFIG_X86_ART
 +
 +static inline int setup_art(void)
 +{
 + return 0;
 +}
 +
 +static inline bool has_art(void)
 +{
 + return false;
 +}
 +
 +static inline int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
 +{
 + return -ENXIO;
 +}
 +static inline int art_to_realtime64(struct timespec64 *realtime, cycle_t art)
 +{
 + return -ENXIO;
 +}
 +static inline int art_to_mono64(struct timespec64 *mono, cycle_t art)
 +{
 + return -ENXIO;
 +}
 +
 +#else
 +
 +extern int setup_art(void);
 +extern bool has_art(void);
 +extern int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art);
 +extern int art_to_realtime64(struct timespec64 *realtime, cycle_t art);
 +extern int art_to_mono64(struct timespec64 *mono, cycle_t art);
 +
 +#endif

 --- /dev/null
 +++ b/arch/x86/kernel/art.c

 +static bool has_art(void)
 +{
 + return art_present;
 +}
 +EXPORT_SYMBOL(has_art);

This exports a static function. Does that work?

 +static int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
 +{
 + if (!checked_art_to_tsc(art))
 + return -ENXIO;
 + return tsc_to_rawmono64(rawmono, art);
 +}
 +EXPORT_SYMBOL(art_to_rawmono64);
 +
 +static int art_to_realtime64(struct timespec64 *realtime, cycle_t art)
 +{
 + if (!checked_art_to_tsc(art))
 + return -ENXIO;
 + return tsc_to_realtime64(realtime, art);
 +}
 +EXPORT_SYMBOL(art_to_realtime64);
 +
 +static int art_to_mono64(struct timespec64 *mono, cycle_t art)
 +{
 + if (!checked_art_to_tsc(art))
 + return -ENXIO;
 + return tsc_to_mono64(mono, art);
 +}
 +EXPORT_SYMBOL(art_to_mono64);

Ditto (three times).

By the way, this series doesn't add users for art_to_mono64() and
art_to_mono64(), right?

Thanks,


Paul Bolle
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-28 Thread Hall, Christopher S


> -Original Message-
> From: John Stultz [mailto:john.stu...@linaro.org]
> Sent: Monday, July 27, 2015 9:11 PM
> To: Hall, Christopher S
> Cc: Thomas Gleixner; Richard Cochran; Ingo Molnar; Kirsher, Jeffrey T;
> Ronciak, John; H. Peter Anvin; x...@kernel.org; lkml;
> net...@vger.kernel.org
> Subject: Re: [PATCH 3/5] Add calls to translate Always Running Timer
> (ART) to system time
> 
> On Mon, Jul 27, 2015 at 5:46 PM, Christopher Hall
>  wrote:
> > +static bool checked_art_to_tsc(cycle_t *tsc)
> > +{
> > +   if (!has_art())
> > +   return false;
> > +   *tsc = art_to_tsc(*tsc);
> > +   return true;
> > +}
> > +
> > +static int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
> > +{
> > +   if (!checked_art_to_tsc())
> > +   return -ENXIO;
> > +   return tsc_to_rawmono64(rawmono, art);
> > +}
> > +EXPORT_SYMBOL(art_to_rawmono64);
> 
> This all seems to assume the TSC is the current clocksource, which it
> may not be if the user has overridden it.

I don't make that assumption.  The counter_to_* functions take a
pointer to a clocksource struct.  They return -ENXIO if that clocksource
doesn’t match the current clocksource.

The tsc_to_* functions pass the tsc clocksource pointer to the counter_to_*
functions.  These tsc conversion functions are called by the art_to_*
functions.

> 
> If instead there were a counter_to_rawmono64() which took the counter
> value and maybe the name of the clocksource (if the strncmp is
> affordable for your use), it might be easier for the core to provide
> an error if the current timekeeping clocksource isn't the one the
> counter value is based on. This would also allow the tsc_to_*()
> midlayers to be dropped (since they don't seem to do much).
> 
> thanks
> -john

Again, thanks for your input.

Chris


Re: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-28 Thread Andy Lutomirski
On Tue, Jul 28, 2015 at 6:18 PM, Hall, Christopher S
 wrote:
>
>
>> -Original Message-
>> From: Andy Lutomirski [mailto:l...@kernel.org]
>> Sent: Monday, July 27, 2015 6:32 PM
>> To: Hall, Christopher S; john.stu...@linaro.org; t...@linutronix.de;
>> richardcoch...@gmail.com; mi...@redhat.com; Kirsher, Jeffrey T; Ronciak,
>> John; h...@zytor.com; x...@kernel.org
>> Cc: linux-kernel@vger.kernel.org; net...@vger.kernel.org; Borislav
>> Petkov
>> Subject: Re: [PATCH 3/5] Add calls to translate Always Running Timer
>> (ART) to system time
>>
>> On 07/27/2015 05:46 PM, Christopher Hall wrote:
>> > * art_to_mono64
>> > * art_to_rawmono64
>> > * art_to_realtime64
>> >
>> > Intel audio and PCH ethernet devices use the Always Running Timer
>> (ART) to
>> > relate their device clock to system time
>> >
>> > Signed-off-by: Christopher Hall 
>> > ---
>> >   arch/x86/Kconfig   |  12 
>> >   arch/x86/include/asm/art.h |  42 ++
>> >   arch/x86/kernel/Makefile   |   1 +
>> >   arch/x86/kernel/art.c  | 134
>> +
>> >   arch/x86/kernel/tsc.c  |   4 ++
>> >   5 files changed, 193 insertions(+)
>> >   create mode 100644 arch/x86/include/asm/art.h
>> >   create mode 100644 arch/x86/kernel/art.c
>> >
>> > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> > index b3a1a5d..1ef9985 100644
>> > --- a/arch/x86/Kconfig
>> > +++ b/arch/x86/Kconfig
>> > @@ -1175,6 +1175,18 @@ config X86_CPUID
>> >   with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
>> >   /dev/cpu/31/cpuid.
>> >
>> > +config X86_ART
>> > +   bool "Always Running Timer"
>> > +   default y
>> > +   depends on X86_TSC
>> > +   ---help---
>> > + This option provides functionality to drivers and devices that
>> use
>> > + the always-running-timer (ART) to correlate their device clock
>> > + counter with the system clock counter. The TSC is *exactly*
>> related
>> > + to the ART by a ratio m/n specified by CPUID leaf 0x15
>> > + (n=EAX,m=EBX). If ART is unused or unavailable there isn't any
>> > + performance impact. It's safe to say Y.
>> > +
>>
>> Is there a good reason to make this optional?
>
> If there aren't any objections, it sound OK to me.  So no, I don't know
> of any good reasons.
>
>>
>> Also, is there *still* no way to ask the thing for its nominal
>> frequnency?  Or can we expect CPUID leaf 16H to work on CPUs that
>> support this and can we expect it to actually work?
>
> There isn't any way to query nominal frequency.  CPUID leaf 0x15 only
> exposes the relationship between ART and TSC.  CPUID leaf 0x16 stays
> the more or less the same and isn't related to ART.
>
> The SDM says "The
>> returned information should not be used for any other purpose as the
>> returned information does not accurately correlate to information /
>> counters returned by other processor interfaces."
>>
>> Also, does this thing let us learn the real time base?  SDM 17.14.4
>> suggests that the ART value isn't affected by "privileged software" (aka
>> buggy/malicious firmware).  Or, alternatively, how do we learn the
>> offset K between ART and scaled TSC?
>
> ART isn't affected by software.  The determination of K used to convert ART to
> TSC is in a footnote (2) in that section of the SDM.  I'm not going to risk
> repeating it here and possibly altering its meaning.
>
>>
>> >   choice
>> > prompt "High Memory Support"
>> > default HIGHMEM4G
>> > diff --git a/arch/x86/include/asm/art.h b/arch/x86/include/asm/art.h
>> > new file mode 100644
>> > index 000..da58ce4
>> > --- /dev/null
>> > +++ b/arch/x86/include/asm/art.h
>> > @@ -0,0 +1,42 @@
>> > +/*
>> > + * x86 ART related functions
>> > + */
>> > +#ifndef _ASM_X86_ART_H
>> > +#define _ASM_X86_ART_H
>> > +
>> > +#ifndef CONFIG_X86_ART
>> > +
>> > +static inline int setup_art(void)
>> > +{
>> > +   return 0;
>> > +}
>> > +
>> > +static inline bool has_art(void)
>> > +{
>> > +   return false;
>> > +}
>> > +
>> > +static inline int art_to_rawmono64(struct timespec64 *rawmono,
>> cycle_t art)
>> > +{
>> > +   return -

RE: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-28 Thread Hall, Christopher S


> -Original Message-
> From: Andy Lutomirski [mailto:l...@kernel.org]
> Sent: Monday, July 27, 2015 6:32 PM
> To: Hall, Christopher S; john.stu...@linaro.org; t...@linutronix.de;
> richardcoch...@gmail.com; mi...@redhat.com; Kirsher, Jeffrey T; Ronciak,
> John; h...@zytor.com; x...@kernel.org
> Cc: linux-kernel@vger.kernel.org; net...@vger.kernel.org; Borislav
> Petkov
> Subject: Re: [PATCH 3/5] Add calls to translate Always Running Timer
> (ART) to system time
> 
> On 07/27/2015 05:46 PM, Christopher Hall wrote:
> > * art_to_mono64
> > * art_to_rawmono64
> > * art_to_realtime64
> >
> > Intel audio and PCH ethernet devices use the Always Running Timer
> (ART) to
> > relate their device clock to system time
> >
> > Signed-off-by: Christopher Hall 
> > ---
> >   arch/x86/Kconfig   |  12 
> >   arch/x86/include/asm/art.h |  42 ++
> >   arch/x86/kernel/Makefile   |   1 +
> >   arch/x86/kernel/art.c  | 134
> +
> >   arch/x86/kernel/tsc.c  |   4 ++
> >   5 files changed, 193 insertions(+)
> >   create mode 100644 arch/x86/include/asm/art.h
> >   create mode 100644 arch/x86/kernel/art.c
> >
> > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> > index b3a1a5d..1ef9985 100644
> > --- a/arch/x86/Kconfig
> > +++ b/arch/x86/Kconfig
> > @@ -1175,6 +1175,18 @@ config X86_CPUID
> >   with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
> >   /dev/cpu/31/cpuid.
> >
> > +config X86_ART
> > +   bool "Always Running Timer"
> > +   default y
> > +   depends on X86_TSC
> > +   ---help---
> > + This option provides functionality to drivers and devices that
> use
> > + the always-running-timer (ART) to correlate their device clock
> > + counter with the system clock counter. The TSC is *exactly*
> related
> > + to the ART by a ratio m/n specified by CPUID leaf 0x15
> > + (n=EAX,m=EBX). If ART is unused or unavailable there isn't any
> > + performance impact. It's safe to say Y.
> > +
> 
> Is there a good reason to make this optional?

If there aren't any objections, it sound OK to me.  So no, I don't know
of any good reasons.

> 
> Also, is there *still* no way to ask the thing for its nominal
> frequnency?  Or can we expect CPUID leaf 16H to work on CPUs that
> support this and can we expect it to actually work?  

There isn't any way to query nominal frequency.  CPUID leaf 0x15 only
exposes the relationship between ART and TSC.  CPUID leaf 0x16 stays
the more or less the same and isn't related to ART.

The SDM says "The
> returned information should not be used for any other purpose as the
> returned information does not accurately correlate to information /
> counters returned by other processor interfaces."
> 
> Also, does this thing let us learn the real time base?  SDM 17.14.4
> suggests that the ART value isn't affected by "privileged software" (aka
> buggy/malicious firmware).  Or, alternatively, how do we learn the
> offset K between ART and scaled TSC?

ART isn't affected by software.  The determination of K used to convert ART to
TSC is in a footnote (2) in that section of the SDM.  I'm not going to risk
repeating it here and possibly altering its meaning.

> 
> >   choice
> > prompt "High Memory Support"
> > default HIGHMEM4G
> > diff --git a/arch/x86/include/asm/art.h b/arch/x86/include/asm/art.h
> > new file mode 100644
> > index 000..da58ce4
> > --- /dev/null
> > +++ b/arch/x86/include/asm/art.h
> > @@ -0,0 +1,42 @@
> > +/*
> > + * x86 ART related functions
> > + */
> > +#ifndef _ASM_X86_ART_H
> > +#define _ASM_X86_ART_H
> > +
> > +#ifndef CONFIG_X86_ART
> > +
> > +static inline int setup_art(void)
> > +{
> > +   return 0;
> > +}
> > +
> > +static inline bool has_art(void)
> > +{
> > +   return false;
> > +}
> > +
> > +static inline int art_to_rawmono64(struct timespec64 *rawmono,
> cycle_t art)
> > +{
> > +   return -ENXIO;
> > +}
> > +static inline int art_to_realtime64(struct timespec64 *realtime,
> cycle_t art)
> > +{
> > +   return -ENXIO;
> > +}
> > +static inline int art_to_mono64(struct timespec64 *mono, cycle_t art)
> > +{
> > +   return -ENXIO;
> > +}
> > +
> > +#else
> > +
> > +extern int setup_art(void);
> > +extern bool has_art(void);
> > +extern int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art);
> > +extern int art_to_rea

RE: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-28 Thread Hall, Christopher S


 -Original Message-
 From: John Stultz [mailto:john.stu...@linaro.org]
 Sent: Monday, July 27, 2015 9:11 PM
 To: Hall, Christopher S
 Cc: Thomas Gleixner; Richard Cochran; Ingo Molnar; Kirsher, Jeffrey T;
 Ronciak, John; H. Peter Anvin; x...@kernel.org; lkml;
 net...@vger.kernel.org
 Subject: Re: [PATCH 3/5] Add calls to translate Always Running Timer
 (ART) to system time
 
 On Mon, Jul 27, 2015 at 5:46 PM, Christopher Hall
 christopher.s.h...@intel.com wrote:
  +static bool checked_art_to_tsc(cycle_t *tsc)
  +{
  +   if (!has_art())
  +   return false;
  +   *tsc = art_to_tsc(*tsc);
  +   return true;
  +}
  +
  +static int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
  +{
  +   if (!checked_art_to_tsc(art))
  +   return -ENXIO;
  +   return tsc_to_rawmono64(rawmono, art);
  +}
  +EXPORT_SYMBOL(art_to_rawmono64);
 
 This all seems to assume the TSC is the current clocksource, which it
 may not be if the user has overridden it.

I don't make that assumption.  The counter_to_* functions take a
pointer to a clocksource struct.  They return -ENXIO if that clocksource
doesn’t match the current clocksource.

The tsc_to_* functions pass the tsc clocksource pointer to the counter_to_*
functions.  These tsc conversion functions are called by the art_to_*
functions.

 
 If instead there were a counter_to_rawmono64() which took the counter
 value and maybe the name of the clocksource (if the strncmp is
 affordable for your use), it might be easier for the core to provide
 an error if the current timekeeping clocksource isn't the one the
 counter value is based on. This would also allow the tsc_to_*()
 midlayers to be dropped (since they don't seem to do much).
 
 thanks
 -john

Again, thanks for your input.

Chris


RE: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-28 Thread Hall, Christopher S


 -Original Message-
 From: Andy Lutomirski [mailto:l...@kernel.org]
 Sent: Monday, July 27, 2015 6:32 PM
 To: Hall, Christopher S; john.stu...@linaro.org; t...@linutronix.de;
 richardcoch...@gmail.com; mi...@redhat.com; Kirsher, Jeffrey T; Ronciak,
 John; h...@zytor.com; x...@kernel.org
 Cc: linux-kernel@vger.kernel.org; net...@vger.kernel.org; Borislav
 Petkov
 Subject: Re: [PATCH 3/5] Add calls to translate Always Running Timer
 (ART) to system time
 
 On 07/27/2015 05:46 PM, Christopher Hall wrote:
  * art_to_mono64
  * art_to_rawmono64
  * art_to_realtime64
 
  Intel audio and PCH ethernet devices use the Always Running Timer
 (ART) to
  relate their device clock to system time
 
  Signed-off-by: Christopher Hall christopher.s.h...@intel.com
  ---
arch/x86/Kconfig   |  12 
arch/x86/include/asm/art.h |  42 ++
arch/x86/kernel/Makefile   |   1 +
arch/x86/kernel/art.c  | 134
 +
arch/x86/kernel/tsc.c  |   4 ++
5 files changed, 193 insertions(+)
create mode 100644 arch/x86/include/asm/art.h
create mode 100644 arch/x86/kernel/art.c
 
  diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
  index b3a1a5d..1ef9985 100644
  --- a/arch/x86/Kconfig
  +++ b/arch/x86/Kconfig
  @@ -1175,6 +1175,18 @@ config X86_CPUID
with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
/dev/cpu/31/cpuid.
 
  +config X86_ART
  +   bool Always Running Timer
  +   default y
  +   depends on X86_TSC
  +   ---help---
  + This option provides functionality to drivers and devices that
 use
  + the always-running-timer (ART) to correlate their device clock
  + counter with the system clock counter. The TSC is *exactly*
 related
  + to the ART by a ratio m/n specified by CPUID leaf 0x15
  + (n=EAX,m=EBX). If ART is unused or unavailable there isn't any
  + performance impact. It's safe to say Y.
  +
 
 Is there a good reason to make this optional?

If there aren't any objections, it sound OK to me.  So no, I don't know
of any good reasons.

 
 Also, is there *still* no way to ask the thing for its nominal
 frequnency?  Or can we expect CPUID leaf 16H to work on CPUs that
 support this and can we expect it to actually work?  

There isn't any way to query nominal frequency.  CPUID leaf 0x15 only
exposes the relationship between ART and TSC.  CPUID leaf 0x16 stays
the more or less the same and isn't related to ART.

The SDM says The
 returned information should not be used for any other purpose as the
 returned information does not accurately correlate to information /
 counters returned by other processor interfaces.
 
 Also, does this thing let us learn the real time base?  SDM 17.14.4
 suggests that the ART value isn't affected by privileged software (aka
 buggy/malicious firmware).  Or, alternatively, how do we learn the
 offset K between ART and scaled TSC?

ART isn't affected by software.  The determination of K used to convert ART to
TSC is in a footnote (2) in that section of the SDM.  I'm not going to risk
repeating it here and possibly altering its meaning.

 
choice
  prompt High Memory Support
  default HIGHMEM4G
  diff --git a/arch/x86/include/asm/art.h b/arch/x86/include/asm/art.h
  new file mode 100644
  index 000..da58ce4
  --- /dev/null
  +++ b/arch/x86/include/asm/art.h
  @@ -0,0 +1,42 @@
  +/*
  + * x86 ART related functions
  + */
  +#ifndef _ASM_X86_ART_H
  +#define _ASM_X86_ART_H
  +
  +#ifndef CONFIG_X86_ART
  +
  +static inline int setup_art(void)
  +{
  +   return 0;
  +}
  +
  +static inline bool has_art(void)
  +{
  +   return false;
  +}
  +
  +static inline int art_to_rawmono64(struct timespec64 *rawmono,
 cycle_t art)
  +{
  +   return -ENXIO;
  +}
  +static inline int art_to_realtime64(struct timespec64 *realtime,
 cycle_t art)
  +{
  +   return -ENXIO;
  +}
  +static inline int art_to_mono64(struct timespec64 *mono, cycle_t art)
  +{
  +   return -ENXIO;
  +}
  +
  +#else
  +
  +extern int setup_art(void);
  +extern bool has_art(void);
  +extern int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art);
  +extern int art_to_realtime64(struct timespec64 *realtime, cycle_t
 art);
  +extern int art_to_mono64(struct timespec64 *mono, cycle_t art);
  +
  +#endif
  +
  +#endif/*_ASM_X86_ART_H*/
  diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
  index 0f15af4..0908311 100644
  --- a/arch/x86/kernel/Makefile
  +++ b/arch/x86/kernel/Makefile
  @@ -109,6 +109,7 @@ obj-$(CONFIG_PERF_EVENTS)   +=
 perf_regs.o
obj-$(CONFIG_TRACING) += tracepoint.o
obj-$(CONFIG_IOSF_MBI)+= iosf_mbi.o
obj-$(CONFIG_PMC_ATOM)+= pmc_atom.o
  +obj-$(CONFIG_X86_ART)  += art.o
 
###
# 64 bit specific files
  diff --git a/arch/x86/kernel/art.c b/arch/x86/kernel/art.c
  new file mode 100644
  index 000..1906cf0
  --- /dev/null
  +++ b/arch/x86

Re: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-28 Thread Andy Lutomirski
On Tue, Jul 28, 2015 at 6:18 PM, Hall, Christopher S
christopher.s.h...@intel.com wrote:


 -Original Message-
 From: Andy Lutomirski [mailto:l...@kernel.org]
 Sent: Monday, July 27, 2015 6:32 PM
 To: Hall, Christopher S; john.stu...@linaro.org; t...@linutronix.de;
 richardcoch...@gmail.com; mi...@redhat.com; Kirsher, Jeffrey T; Ronciak,
 John; h...@zytor.com; x...@kernel.org
 Cc: linux-kernel@vger.kernel.org; net...@vger.kernel.org; Borislav
 Petkov
 Subject: Re: [PATCH 3/5] Add calls to translate Always Running Timer
 (ART) to system time

 On 07/27/2015 05:46 PM, Christopher Hall wrote:
  * art_to_mono64
  * art_to_rawmono64
  * art_to_realtime64
 
  Intel audio and PCH ethernet devices use the Always Running Timer
 (ART) to
  relate their device clock to system time
 
  Signed-off-by: Christopher Hall christopher.s.h...@intel.com
  ---
arch/x86/Kconfig   |  12 
arch/x86/include/asm/art.h |  42 ++
arch/x86/kernel/Makefile   |   1 +
arch/x86/kernel/art.c  | 134
 +
arch/x86/kernel/tsc.c  |   4 ++
5 files changed, 193 insertions(+)
create mode 100644 arch/x86/include/asm/art.h
create mode 100644 arch/x86/kernel/art.c
 
  diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
  index b3a1a5d..1ef9985 100644
  --- a/arch/x86/Kconfig
  +++ b/arch/x86/Kconfig
  @@ -1175,6 +1175,18 @@ config X86_CPUID
with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
/dev/cpu/31/cpuid.
 
  +config X86_ART
  +   bool Always Running Timer
  +   default y
  +   depends on X86_TSC
  +   ---help---
  + This option provides functionality to drivers and devices that
 use
  + the always-running-timer (ART) to correlate their device clock
  + counter with the system clock counter. The TSC is *exactly*
 related
  + to the ART by a ratio m/n specified by CPUID leaf 0x15
  + (n=EAX,m=EBX). If ART is unused or unavailable there isn't any
  + performance impact. It's safe to say Y.
  +

 Is there a good reason to make this optional?

 If there aren't any objections, it sound OK to me.  So no, I don't know
 of any good reasons.


 Also, is there *still* no way to ask the thing for its nominal
 frequnency?  Or can we expect CPUID leaf 16H to work on CPUs that
 support this and can we expect it to actually work?

 There isn't any way to query nominal frequency.  CPUID leaf 0x15 only
 exposes the relationship between ART and TSC.  CPUID leaf 0x16 stays
 the more or less the same and isn't related to ART.

 The SDM says The
 returned information should not be used for any other purpose as the
 returned information does not accurately correlate to information /
 counters returned by other processor interfaces.

 Also, does this thing let us learn the real time base?  SDM 17.14.4
 suggests that the ART value isn't affected by privileged software (aka
 buggy/malicious firmware).  Or, alternatively, how do we learn the
 offset K between ART and scaled TSC?

 ART isn't affected by software.  The determination of K used to convert ART to
 TSC is in a footnote (2) in that section of the SDM.  I'm not going to risk
 repeating it here and possibly altering its meaning.


choice
  prompt High Memory Support
  default HIGHMEM4G
  diff --git a/arch/x86/include/asm/art.h b/arch/x86/include/asm/art.h
  new file mode 100644
  index 000..da58ce4
  --- /dev/null
  +++ b/arch/x86/include/asm/art.h
  @@ -0,0 +1,42 @@
  +/*
  + * x86 ART related functions
  + */
  +#ifndef _ASM_X86_ART_H
  +#define _ASM_X86_ART_H
  +
  +#ifndef CONFIG_X86_ART
  +
  +static inline int setup_art(void)
  +{
  +   return 0;
  +}
  +
  +static inline bool has_art(void)
  +{
  +   return false;
  +}
  +
  +static inline int art_to_rawmono64(struct timespec64 *rawmono,
 cycle_t art)
  +{
  +   return -ENXIO;
  +}
  +static inline int art_to_realtime64(struct timespec64 *realtime,
 cycle_t art)
  +{
  +   return -ENXIO;
  +}
  +static inline int art_to_mono64(struct timespec64 *mono, cycle_t art)
  +{
  +   return -ENXIO;
  +}
  +
  +#else
  +
  +extern int setup_art(void);
  +extern bool has_art(void);
  +extern int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art);
  +extern int art_to_realtime64(struct timespec64 *realtime, cycle_t
 art);
  +extern int art_to_mono64(struct timespec64 *mono, cycle_t art);
  +
  +#endif
  +
  +#endif/*_ASM_X86_ART_H*/
  diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
  index 0f15af4..0908311 100644
  --- a/arch/x86/kernel/Makefile
  +++ b/arch/x86/kernel/Makefile
  @@ -109,6 +109,7 @@ obj-$(CONFIG_PERF_EVENTS)   +=
 perf_regs.o
obj-$(CONFIG_TRACING) += tracepoint.o
obj-$(CONFIG_IOSF_MBI)+= iosf_mbi.o
obj-$(CONFIG_PMC_ATOM)+= pmc_atom.o
  +obj-$(CONFIG_X86_ART)  += art.o
 
###
# 64 bit specific files
  diff --git a/arch/x86/kernel/art.c b/arch/x86

Re: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-27 Thread John Stultz
On Mon, Jul 27, 2015 at 5:46 PM, Christopher Hall
 wrote:
> +static bool checked_art_to_tsc(cycle_t *tsc)
> +{
> +   if (!has_art())
> +   return false;
> +   *tsc = art_to_tsc(*tsc);
> +   return true;
> +}
> +
> +static int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
> +{
> +   if (!checked_art_to_tsc())
> +   return -ENXIO;
> +   return tsc_to_rawmono64(rawmono, art);
> +}
> +EXPORT_SYMBOL(art_to_rawmono64);

This all seems to assume the TSC is the current clocksource, which it
may not be if the user has overridden it.

If instead there were a counter_to_rawmono64() which took the counter
value and maybe the name of the clocksource (if the strncmp is
affordable for your use), it might be easier for the core to provide
an error if the current timekeeping clocksource isn't the one the
counter value is based on. This would also allow the tsc_to_*()
midlayers to be dropped (since they don't seem to do much).

thanks
-john
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-27 Thread Andy Lutomirski

On 07/27/2015 05:46 PM, Christopher Hall wrote:

* art_to_mono64
* art_to_rawmono64
* art_to_realtime64

Intel audio and PCH ethernet devices use the Always Running Timer (ART) to
relate their device clock to system time

Signed-off-by: Christopher Hall 
---
  arch/x86/Kconfig   |  12 
  arch/x86/include/asm/art.h |  42 ++
  arch/x86/kernel/Makefile   |   1 +
  arch/x86/kernel/art.c  | 134 +
  arch/x86/kernel/tsc.c  |   4 ++
  5 files changed, 193 insertions(+)
  create mode 100644 arch/x86/include/asm/art.h
  create mode 100644 arch/x86/kernel/art.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b3a1a5d..1ef9985 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1175,6 +1175,18 @@ config X86_CPUID
  with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
  /dev/cpu/31/cpuid.

+config X86_ART
+   bool "Always Running Timer"
+   default y
+   depends on X86_TSC
+   ---help---
+ This option provides functionality to drivers and devices that use
+ the always-running-timer (ART) to correlate their device clock
+ counter with the system clock counter. The TSC is *exactly* related
+ to the ART by a ratio m/n specified by CPUID leaf 0x15
+ (n=EAX,m=EBX). If ART is unused or unavailable there isn't any
+ performance impact. It's safe to say Y.
+


Is there a good reason to make this optional?

Also, is there *still* no way to ask the thing for its nominal 
frequnency?  Or can we expect CPUID leaf 16H to work on CPUs that 
support this and can we expect it to actually work?  The SDM says "The 
returned information should not be used for any other purpose as the 
returned information does not accurately correlate to information / 
counters returned by other processor interfaces."


Also, does this thing let us learn the real time base?  SDM 17.14.4 
suggests that the ART value isn't affected by "privileged software" (aka 
buggy/malicious firmware).  Or, alternatively, how do we learn the 
offset K between ART and scaled TSC?



  choice
prompt "High Memory Support"
default HIGHMEM4G
diff --git a/arch/x86/include/asm/art.h b/arch/x86/include/asm/art.h
new file mode 100644
index 000..da58ce4
--- /dev/null
+++ b/arch/x86/include/asm/art.h
@@ -0,0 +1,42 @@
+/*
+ * x86 ART related functions
+ */
+#ifndef _ASM_X86_ART_H
+#define _ASM_X86_ART_H
+
+#ifndef CONFIG_X86_ART
+
+static inline int setup_art(void)
+{
+   return 0;
+}
+
+static inline bool has_art(void)
+{
+   return false;
+}
+
+static inline int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
+{
+   return -ENXIO;
+}
+static inline int art_to_realtime64(struct timespec64 *realtime, cycle_t art)
+{
+   return -ENXIO;
+}
+static inline int art_to_mono64(struct timespec64 *mono, cycle_t art)
+{
+   return -ENXIO;
+}
+
+#else
+
+extern int setup_art(void);
+extern bool has_art(void);
+extern int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art);
+extern int art_to_realtime64(struct timespec64 *realtime, cycle_t art);
+extern int art_to_mono64(struct timespec64 *mono, cycle_t art);
+
+#endif
+
+#endif/*_ASM_X86_ART_H*/
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0f15af4..0908311 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_PERF_EVENTS)   += perf_regs.o
  obj-$(CONFIG_TRACING) += tracepoint.o
  obj-$(CONFIG_IOSF_MBI)+= iosf_mbi.o
  obj-$(CONFIG_PMC_ATOM)+= pmc_atom.o
+obj-$(CONFIG_X86_ART)  += art.o

  ###
  # 64 bit specific files
diff --git a/arch/x86/kernel/art.c b/arch/x86/kernel/art.c
new file mode 100644
index 000..1906cf0
--- /dev/null
+++ b/arch/x86/kernel/art.c
@@ -0,0 +1,134 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CPUID_ART_LEAF 0x15
+
+static bool art_present;
+
+static struct art_state {
+   seqcount_t seq;
+   u32 art_ratio_numerator;
+   u32 art_ratio_denominator;
+


This needs much better comments, IMO, including some discussion of how 
the locking works.



+   cycle_t prev_art;
+   cycle_t prev_tsc_corr_art; /*This is the TSC value corresponding to
+prev_art */
+   u32 tsc_remainder;
+} art_state cacheline_aligned;
+
+static DEFINE_RAW_SPINLOCK(art_lock);
+
+#define MIN_DENOMINATOR 2
+int setup_art(void)
+{
+   if (boot_cpu_data.cpuid_level < CPUID_ART_LEAF)
+   return 0;
+   art_state.art_ratio_denominator = cpuid_eax(CPUID_ART_LEAF);
+   if (art_state.art_ratio_denominator < MIN_DENOMINATOR)
+   return 0;
+   art_state.art_ratio_numerator = cpuid_ebx(CPUID_ART_LEAF);
+
+   art_present = true;
+   return 0;
+}
+
+static bool has_art(void)
+{
+   return art_present;
+}
+EXPORT_SYMBOL(has_art);


IMO this 

[PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-27 Thread Christopher Hall
* art_to_mono64
* art_to_rawmono64
* art_to_realtime64

Intel audio and PCH ethernet devices use the Always Running Timer (ART) to
relate their device clock to system time

Signed-off-by: Christopher Hall 
---
 arch/x86/Kconfig   |  12 
 arch/x86/include/asm/art.h |  42 ++
 arch/x86/kernel/Makefile   |   1 +
 arch/x86/kernel/art.c  | 134 +
 arch/x86/kernel/tsc.c  |   4 ++
 5 files changed, 193 insertions(+)
 create mode 100644 arch/x86/include/asm/art.h
 create mode 100644 arch/x86/kernel/art.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b3a1a5d..1ef9985 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1175,6 +1175,18 @@ config X86_CPUID
  with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
  /dev/cpu/31/cpuid.
 
+config X86_ART
+   bool "Always Running Timer"
+   default y
+   depends on X86_TSC
+   ---help---
+ This option provides functionality to drivers and devices that use
+ the always-running-timer (ART) to correlate their device clock
+ counter with the system clock counter. The TSC is *exactly* related
+ to the ART by a ratio m/n specified by CPUID leaf 0x15
+ (n=EAX,m=EBX). If ART is unused or unavailable there isn't any
+ performance impact. It's safe to say Y.
+
 choice
prompt "High Memory Support"
default HIGHMEM4G
diff --git a/arch/x86/include/asm/art.h b/arch/x86/include/asm/art.h
new file mode 100644
index 000..da58ce4
--- /dev/null
+++ b/arch/x86/include/asm/art.h
@@ -0,0 +1,42 @@
+/*
+ * x86 ART related functions
+ */
+#ifndef _ASM_X86_ART_H
+#define _ASM_X86_ART_H
+
+#ifndef CONFIG_X86_ART
+
+static inline int setup_art(void)
+{
+   return 0;
+}
+
+static inline bool has_art(void)
+{
+   return false;
+}
+
+static inline int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
+{
+   return -ENXIO;
+}
+static inline int art_to_realtime64(struct timespec64 *realtime, cycle_t art)
+{
+   return -ENXIO;
+}
+static inline int art_to_mono64(struct timespec64 *mono, cycle_t art)
+{
+   return -ENXIO;
+}
+
+#else
+
+extern int setup_art(void);
+extern bool has_art(void);
+extern int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art);
+extern int art_to_realtime64(struct timespec64 *realtime, cycle_t art);
+extern int art_to_mono64(struct timespec64 *mono, cycle_t art);
+
+#endif
+
+#endif/*_ASM_X86_ART_H*/
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0f15af4..0908311 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_PERF_EVENTS)   += perf_regs.o
 obj-$(CONFIG_TRACING)  += tracepoint.o
 obj-$(CONFIG_IOSF_MBI) += iosf_mbi.o
 obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
+obj-$(CONFIG_X86_ART)  += art.o
 
 ###
 # 64 bit specific files
diff --git a/arch/x86/kernel/art.c b/arch/x86/kernel/art.c
new file mode 100644
index 000..1906cf0
--- /dev/null
+++ b/arch/x86/kernel/art.c
@@ -0,0 +1,134 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CPUID_ART_LEAF 0x15
+
+static bool art_present;
+
+static struct art_state {
+   seqcount_t seq;
+   u32 art_ratio_numerator;
+   u32 art_ratio_denominator;
+
+   cycle_t prev_art;
+   cycle_t prev_tsc_corr_art; /*This is the TSC value corresponding to
+prev_art */
+   u32 tsc_remainder;
+} art_state cacheline_aligned;
+
+static DEFINE_RAW_SPINLOCK(art_lock);
+
+#define MIN_DENOMINATOR 2
+int setup_art(void)
+{
+   if (boot_cpu_data.cpuid_level < CPUID_ART_LEAF)
+   return 0;
+   art_state.art_ratio_denominator = cpuid_eax(CPUID_ART_LEAF);
+   if (art_state.art_ratio_denominator < MIN_DENOMINATOR)
+   return 0;
+   art_state.art_ratio_numerator = cpuid_ebx(CPUID_ART_LEAF);
+
+   art_present = true;
+   return 0;
+}
+
+static bool has_art(void)
+{
+   return art_present;
+}
+EXPORT_SYMBOL(has_art);
+
+#define ROLLOVER_THRESHOLD (2ULL << 23)
+
+static u32 art_scale(struct art_state *art_state, cycle_t *art)
+{
+   u32 rem;
+
+   *art *= art_state->art_ratio_numerator;
+
+   switch (art_state->art_ratio_denominator) {
+   default:
+   rem = do_div(*art, art_state->art_ratio_denominator);
+   case 2:
+   rem = *art & 0x1;
+   *art >>= 1;
+   }
+   return rem + art_state->tsc_remainder;
+}
+
+static cycle_t art_to_tsc(cycle_t art)
+{
+   unsigned seq;
+   cycle_t tsc_next;
+   u32 rem_next;
+   bool backward = false;
+   unsigned long flags;
+
+   do {
+   seq = read_seqcount_begin(_state.seq);
+
+   if (art < art_state.prev_art &&
+   art_state.prev_art - art < ROLLOVER_THRESHOLD) {
+   tsc_next = 

[PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-27 Thread Christopher Hall
* art_to_mono64
* art_to_rawmono64
* art_to_realtime64

Intel audio and PCH ethernet devices use the Always Running Timer (ART) to
relate their device clock to system time

Signed-off-by: Christopher Hall christopher.s.h...@intel.com
---
 arch/x86/Kconfig   |  12 
 arch/x86/include/asm/art.h |  42 ++
 arch/x86/kernel/Makefile   |   1 +
 arch/x86/kernel/art.c  | 134 +
 arch/x86/kernel/tsc.c  |   4 ++
 5 files changed, 193 insertions(+)
 create mode 100644 arch/x86/include/asm/art.h
 create mode 100644 arch/x86/kernel/art.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b3a1a5d..1ef9985 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1175,6 +1175,18 @@ config X86_CPUID
  with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
  /dev/cpu/31/cpuid.
 
+config X86_ART
+   bool Always Running Timer
+   default y
+   depends on X86_TSC
+   ---help---
+ This option provides functionality to drivers and devices that use
+ the always-running-timer (ART) to correlate their device clock
+ counter with the system clock counter. The TSC is *exactly* related
+ to the ART by a ratio m/n specified by CPUID leaf 0x15
+ (n=EAX,m=EBX). If ART is unused or unavailable there isn't any
+ performance impact. It's safe to say Y.
+
 choice
prompt High Memory Support
default HIGHMEM4G
diff --git a/arch/x86/include/asm/art.h b/arch/x86/include/asm/art.h
new file mode 100644
index 000..da58ce4
--- /dev/null
+++ b/arch/x86/include/asm/art.h
@@ -0,0 +1,42 @@
+/*
+ * x86 ART related functions
+ */
+#ifndef _ASM_X86_ART_H
+#define _ASM_X86_ART_H
+
+#ifndef CONFIG_X86_ART
+
+static inline int setup_art(void)
+{
+   return 0;
+}
+
+static inline bool has_art(void)
+{
+   return false;
+}
+
+static inline int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
+{
+   return -ENXIO;
+}
+static inline int art_to_realtime64(struct timespec64 *realtime, cycle_t art)
+{
+   return -ENXIO;
+}
+static inline int art_to_mono64(struct timespec64 *mono, cycle_t art)
+{
+   return -ENXIO;
+}
+
+#else
+
+extern int setup_art(void);
+extern bool has_art(void);
+extern int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art);
+extern int art_to_realtime64(struct timespec64 *realtime, cycle_t art);
+extern int art_to_mono64(struct timespec64 *mono, cycle_t art);
+
+#endif
+
+#endif/*_ASM_X86_ART_H*/
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0f15af4..0908311 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_PERF_EVENTS)   += perf_regs.o
 obj-$(CONFIG_TRACING)  += tracepoint.o
 obj-$(CONFIG_IOSF_MBI) += iosf_mbi.o
 obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
+obj-$(CONFIG_X86_ART)  += art.o
 
 ###
 # 64 bit specific files
diff --git a/arch/x86/kernel/art.c b/arch/x86/kernel/art.c
new file mode 100644
index 000..1906cf0
--- /dev/null
+++ b/arch/x86/kernel/art.c
@@ -0,0 +1,134 @@
+#include asm/tsc.h
+#include asm/cpufeature.h
+#include asm/processor.h
+#include linux/spinlock.h
+#include linux/seqlock.h
+
+#define CPUID_ART_LEAF 0x15
+
+static bool art_present;
+
+static struct art_state {
+   seqcount_t seq;
+   u32 art_ratio_numerator;
+   u32 art_ratio_denominator;
+
+   cycle_t prev_art;
+   cycle_t prev_tsc_corr_art; /*This is the TSC value corresponding to
+prev_art */
+   u32 tsc_remainder;
+} art_state cacheline_aligned;
+
+static DEFINE_RAW_SPINLOCK(art_lock);
+
+#define MIN_DENOMINATOR 2
+int setup_art(void)
+{
+   if (boot_cpu_data.cpuid_level  CPUID_ART_LEAF)
+   return 0;
+   art_state.art_ratio_denominator = cpuid_eax(CPUID_ART_LEAF);
+   if (art_state.art_ratio_denominator  MIN_DENOMINATOR)
+   return 0;
+   art_state.art_ratio_numerator = cpuid_ebx(CPUID_ART_LEAF);
+
+   art_present = true;
+   return 0;
+}
+
+static bool has_art(void)
+{
+   return art_present;
+}
+EXPORT_SYMBOL(has_art);
+
+#define ROLLOVER_THRESHOLD (2ULL  23)
+
+static u32 art_scale(struct art_state *art_state, cycle_t *art)
+{
+   u32 rem;
+
+   *art *= art_state-art_ratio_numerator;
+
+   switch (art_state-art_ratio_denominator) {
+   default:
+   rem = do_div(*art, art_state-art_ratio_denominator);
+   case 2:
+   rem = *art  0x1;
+   *art = 1;
+   }
+   return rem + art_state-tsc_remainder;
+}
+
+static cycle_t art_to_tsc(cycle_t art)
+{
+   unsigned seq;
+   cycle_t tsc_next;
+   u32 rem_next;
+   bool backward = false;
+   unsigned long flags;
+
+   do {
+   seq = read_seqcount_begin(art_state.seq);
+
+   if (art  art_state.prev_art 
+   art_state.prev_art - 

Re: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-27 Thread Andy Lutomirski

On 07/27/2015 05:46 PM, Christopher Hall wrote:

* art_to_mono64
* art_to_rawmono64
* art_to_realtime64

Intel audio and PCH ethernet devices use the Always Running Timer (ART) to
relate their device clock to system time

Signed-off-by: Christopher Hall christopher.s.h...@intel.com
---
  arch/x86/Kconfig   |  12 
  arch/x86/include/asm/art.h |  42 ++
  arch/x86/kernel/Makefile   |   1 +
  arch/x86/kernel/art.c  | 134 +
  arch/x86/kernel/tsc.c  |   4 ++
  5 files changed, 193 insertions(+)
  create mode 100644 arch/x86/include/asm/art.h
  create mode 100644 arch/x86/kernel/art.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b3a1a5d..1ef9985 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1175,6 +1175,18 @@ config X86_CPUID
  with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
  /dev/cpu/31/cpuid.

+config X86_ART
+   bool Always Running Timer
+   default y
+   depends on X86_TSC
+   ---help---
+ This option provides functionality to drivers and devices that use
+ the always-running-timer (ART) to correlate their device clock
+ counter with the system clock counter. The TSC is *exactly* related
+ to the ART by a ratio m/n specified by CPUID leaf 0x15
+ (n=EAX,m=EBX). If ART is unused or unavailable there isn't any
+ performance impact. It's safe to say Y.
+


Is there a good reason to make this optional?

Also, is there *still* no way to ask the thing for its nominal 
frequnency?  Or can we expect CPUID leaf 16H to work on CPUs that 
support this and can we expect it to actually work?  The SDM says The 
returned information should not be used for any other purpose as the 
returned information does not accurately correlate to information / 
counters returned by other processor interfaces.


Also, does this thing let us learn the real time base?  SDM 17.14.4 
suggests that the ART value isn't affected by privileged software (aka 
buggy/malicious firmware).  Or, alternatively, how do we learn the 
offset K between ART and scaled TSC?



  choice
prompt High Memory Support
default HIGHMEM4G
diff --git a/arch/x86/include/asm/art.h b/arch/x86/include/asm/art.h
new file mode 100644
index 000..da58ce4
--- /dev/null
+++ b/arch/x86/include/asm/art.h
@@ -0,0 +1,42 @@
+/*
+ * x86 ART related functions
+ */
+#ifndef _ASM_X86_ART_H
+#define _ASM_X86_ART_H
+
+#ifndef CONFIG_X86_ART
+
+static inline int setup_art(void)
+{
+   return 0;
+}
+
+static inline bool has_art(void)
+{
+   return false;
+}
+
+static inline int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
+{
+   return -ENXIO;
+}
+static inline int art_to_realtime64(struct timespec64 *realtime, cycle_t art)
+{
+   return -ENXIO;
+}
+static inline int art_to_mono64(struct timespec64 *mono, cycle_t art)
+{
+   return -ENXIO;
+}
+
+#else
+
+extern int setup_art(void);
+extern bool has_art(void);
+extern int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art);
+extern int art_to_realtime64(struct timespec64 *realtime, cycle_t art);
+extern int art_to_mono64(struct timespec64 *mono, cycle_t art);
+
+#endif
+
+#endif/*_ASM_X86_ART_H*/
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0f15af4..0908311 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -109,6 +109,7 @@ obj-$(CONFIG_PERF_EVENTS)   += perf_regs.o
  obj-$(CONFIG_TRACING) += tracepoint.o
  obj-$(CONFIG_IOSF_MBI)+= iosf_mbi.o
  obj-$(CONFIG_PMC_ATOM)+= pmc_atom.o
+obj-$(CONFIG_X86_ART)  += art.o

  ###
  # 64 bit specific files
diff --git a/arch/x86/kernel/art.c b/arch/x86/kernel/art.c
new file mode 100644
index 000..1906cf0
--- /dev/null
+++ b/arch/x86/kernel/art.c
@@ -0,0 +1,134 @@
+#include asm/tsc.h
+#include asm/cpufeature.h
+#include asm/processor.h
+#include linux/spinlock.h
+#include linux/seqlock.h
+
+#define CPUID_ART_LEAF 0x15
+
+static bool art_present;
+
+static struct art_state {
+   seqcount_t seq;
+   u32 art_ratio_numerator;
+   u32 art_ratio_denominator;
+


This needs much better comments, IMO, including some discussion of how 
the locking works.



+   cycle_t prev_art;
+   cycle_t prev_tsc_corr_art; /*This is the TSC value corresponding to
+prev_art */
+   u32 tsc_remainder;
+} art_state cacheline_aligned;
+
+static DEFINE_RAW_SPINLOCK(art_lock);
+
+#define MIN_DENOMINATOR 2
+int setup_art(void)
+{
+   if (boot_cpu_data.cpuid_level  CPUID_ART_LEAF)
+   return 0;
+   art_state.art_ratio_denominator = cpuid_eax(CPUID_ART_LEAF);
+   if (art_state.art_ratio_denominator  MIN_DENOMINATOR)
+   return 0;
+   art_state.art_ratio_numerator = cpuid_ebx(CPUID_ART_LEAF);
+
+   art_present = true;
+   return 0;
+}
+
+static 

Re: [PATCH 3/5] Add calls to translate Always Running Timer (ART) to system time

2015-07-27 Thread John Stultz
On Mon, Jul 27, 2015 at 5:46 PM, Christopher Hall
christopher.s.h...@intel.com wrote:
 +static bool checked_art_to_tsc(cycle_t *tsc)
 +{
 +   if (!has_art())
 +   return false;
 +   *tsc = art_to_tsc(*tsc);
 +   return true;
 +}
 +
 +static int art_to_rawmono64(struct timespec64 *rawmono, cycle_t art)
 +{
 +   if (!checked_art_to_tsc(art))
 +   return -ENXIO;
 +   return tsc_to_rawmono64(rawmono, art);
 +}
 +EXPORT_SYMBOL(art_to_rawmono64);

This all seems to assume the TSC is the current clocksource, which it
may not be if the user has overridden it.

If instead there were a counter_to_rawmono64() which took the counter
value and maybe the name of the clocksource (if the strncmp is
affordable for your use), it might be easier for the core to provide
an error if the current timekeeping clocksource isn't the one the
counter value is based on. This would also allow the tsc_to_*()
midlayers to be dropped (since they don't seem to do much).

thanks
-john
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/