lkml.org 
[lkml]   [2005]   [Jul]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    SubjectRe: long delays (possibly infinite) in time_interpolator_get_counter
    From
    Date

    Ok, here's an optimization that should help reduce contention on the
    cmpxchg, has zero impact on the nojitter path, and doesn't require any
    changes to fsys. When a caller already had the xtime_lock write lock
    there's no need to fight with other CPUs for the cmpxchg. The other
    "reader" CPUs will have to fetch it again since a seqlock write is in
    progress. Therefore we can simplify this path as shown below. The
    write is atomic, and we don't care if another CPU has changed last_cycle
    since it can't return the value until the write lock is released. This
    has only been compile tested, but I'm interested to hear your opinion.
    Thanks,

    Alex


    diff -r cff8d3633e9c kernel/timer.c
    --- a/kernel/timer.c Fri Jul 29 22:01:15 2005
    +++ b/kernel/timer.c Sun Jul 31 10:25:41 2005
    @@ -1452,10 +1452,34 @@
    return time_interpolator_get_cycles(src);
    }

    +static inline u64 time_interpolator_get_counter_locked(void)
    +{
    + unsigned int src = time_interpolator->source;
    +
    + if (time_interpolator->jitter)
    + {
    + u64 lcycle = time_interpolator->last_cycle;
    + u64 now = time_interpolator_get_cycles(src);
    +
    + if (lcycle && time_after(lcycle, now))
    + return lcycle;
    +
    + /*
    + * This path is called when holding the xtime write lock.
    + * This allows us to avoid the contention of the cmpxchg
    + * in get_counter, and still ensures jitter protection.
    + */
    + time_interpolator->last_cycle = now;
    + return now;
    + }
    + else
    + return time_interpolator_get_cycles(src);
    +}
    +
    void time_interpolator_reset(void)
    {
    time_interpolator->offset = 0;
    - time_interpolator->last_counter = time_interpolator_get_counter();
    + time_interpolator->last_counter = time_interpolator_get_counter_locked();
    }

    #define GET_TI_NSECS(count,i) (((((count) - i->last_counter) & (i)->mask) * (i)->nsec_per_cyc) >> (i)->shift)
    @@ -1490,7 +1514,7 @@
    * and the tuning logic insures that.
    */

    - counter = time_interpolator_get_counter();
    + counter = time_interpolator_get_counter_locked();
    offset = time_interpolator->offset + GET_TI_NSECS(counter, time_interpolator);

    if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)

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

    \
     
     \ /
      Last update: 2005-07-31 19:06    [W:9.290 / U:0.108 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site