On Mon, 12 Oct 2015, Christopher S. Hall wrote:
> Another representative use case of time sync and the correlated
> clocksource (in addition to PTP noted above) is PTP synchronized
> audio.

This wants to be a seperate patch, really.
 
> +/* This needs to be 3 or greater for backtracking to be useful */

Why?

> +#define SHADOW_HISTORY_DEPTH 7

And that number is 7 because?

>  static DEFINE_RAW_SPINLOCK(timekeeper_lock);
> -static struct timekeeper shadow_timekeeper;
> +static struct timekeeper shadow_timekeeper[SHADOW_HISTORY_DEPTH];
> +static int shadow_index = -1; /* incremented to zero in timekeeping_init() */

What's the point of this? Aside of that, please do not use tail comments.

> +static bool shadow_timekeeper_full;

That's silly. Make DEPTH a power of 2 and do:

       idx = (idx + 1) & (DEPTH - 1);

> +/*
> + * Modifies shadow index argument to point to the next array element
> + * Returns bool indicating shadow array fullness after the update
> + */
> +static bool get_next_shadow_index(int *shadow_index_out)
> +{
> +     *shadow_index_out = (shadow_index + 1) % SHADOW_HISTORY_DEPTH;
> +     /*
> +      * If shadow timekeeper is full it stays full, otherwise compute
> +      * the next value based on whether the index rolls over
> +      */
> +     return shadow_timekeeper_full ?
> +             true : *shadow_index_out < shadow_index;

All this can go away.

> +     if (action & TK_MIRROR) {
> +             int next_shadow_index;
> +             bool next_shadow_full =
> +                     get_next_shadow_index(&next_shadow_index);
> +             memcpy(shadow_timekeeper+next_shadow_index,
> +                    &tk_core.timekeeper, sizeof(tk_core.timekeeper));
> +             shadow_index = next_shadow_index;
> +             shadow_timekeeper_full = next_shadow_full;

Ditto.

> +     }
>  }
>  
>  /**
> @@ -884,6 +923,142 @@ EXPORT_SYMBOL(getnstime_raw_and_real);
>  
>  #endif /* CONFIG_NTP_PPS */
>  
> +/*
> + * Iterator-like function which can be called multiple times to return the
> + * previous shadow_index
> + * Returns false when finding previous is not possible because:
> + * - The array is not full
> + * - The previous shadow_index refers to an entry that may be in-flight
> + */
> +static bool get_prev_shadow_index(int *shadow_index_io)
> +{
> +     int guard_index;
> +     int ret = (*shadow_index_io - 1) % SHADOW_HISTORY_DEPTH;
> +
> +     ret += ret < 0 ? SHADOW_HISTORY_DEPTH : 0;
> +     /*
> +      * guard_index references the next shadow entry, assume that this
> +      * isn't valid since its not protected by sequence lock
> +      */
> +     get_next_shadow_index(&guard_index);
> +     /* if the array isn't full and index references top (invalid) entry */
> +     if (!shadow_timekeeper_full && ret > *shadow_index_io)
> +             return false;
> +     /* the next entry may be in-flight and may be invalid  */
> +     if (ret == guard_index)
> +             return false;
> +     /* Also make sure that entry is valid based on current shadow_index */
> +     *shadow_index_io = ret;
> +     return true;

You surely try hard to do stuff in the most unreadable way. 

> +/**
> + * get_correlated_timestamp - Get a correlated timestamp
> + * @crs: conversion between correlated clock and system clock
> + * @crt: callback to get simultaneous device and correlated clock value *or*
> + *   contains a valid correlated clock value and NULL callback
> + *
> + * Reads a timestamp from a device and correlates it to system time.  This
> + * function can be used in two ways.  If a non-NULL get_ts function pointer 
> is
> + * supplied in @crt, this function is called within the retry loop to
> + * read the current correlated clock value and associated device time.
> + * Otherwise (get_ts is NULL) a correlated clock value is supplied and
> + * the history in shadow_timekeeper is consulted if necessary.
> + */
> +int get_correlated_timestamp(struct correlated_ts *crt,
> +                          struct correlated_cs *crs)
> +{
> +     struct timekeeper *tk = &tk_core.timekeeper;
> +     unsigned long seq;
> +     cycles_t cycles, cycles_now, cycles_last;
> +     ktime_t base;
> +     s64 nsecs;
> +     int ret;
> +
> +     do {
> +             seq = read_seqcount_begin(&tk_core.seq);
> +             /*
> +              * Verify that the correlated clocksoure is related to
> +              * the currently installed timekeeper clocksoure
> +              */
> +             if (tk->tkr_mono.clock != crs->related_cs)
> +                     return -ENODEV;
> +
> +             /*
> +              * Get a timestamp from the device if get_ts is non-NULL
> +              */
> +             if( crt->get_ts ) {
> +                     ret = crt->get_ts(crt);
> +                     if (ret)
> +                             return ret;
> +             }

What's the point of this? Why are you not making the few lines which
you can actually reuse a helper function and leave the PTP code alone?

> -- 
> 2.1.4

So I reached enf of patch and did not find anything in
timekeeping_init() which tells that the index is incremented to 0. It
really would need a comment, but why do you want to do that at all. It
does not matter whether the first entry is at 0 or 1. You need a
validity check for the entries anyway.

Thanks,

        tglx



--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to