Re: [PATCH 1/2] timer: introduce upper bound timers

Thomas Gleixner
2022-03-24T13:54:31Z

On Thu, Mar 24 2022 at 13:28, Thomas Gleixner wrote:
> On Wed, Mar 23 2022 at 12:16, Artem Savkov wrote:
>> Add TIMER_UPPER_BOUND flag which allows creation of timers that would
>> expire at most at specified time or earlier.
>>
>> This was previously discussed here:
>> https://lore.kernel.org/all/20210302001054.4qgrvnkltvkgikzr@treble/T/#u
>
> please add the context to the changelog. A link is only supplemental
> information and does not replace content.
>
>> static inline unsigned calc_index(unsigned long expires, unsigned lvl,
>> - unsigned long *bucket_expiry)
>> + unsigned long *bucket_expiry, bool upper_bound)
>> {
>>
>> /*
>> @@ -501,34 +501,39 @@ static inline unsigned calc_index(unsigned long expires, unsigned lvl,
>> * - Truncation of the expiry time in the outer wheel levels
>> *
>> * Round up with level granularity to prevent this.
>> + * Do not perform round up in case of upper bound timer.
>> */
>> - expires = (expires + LVL_GRAN(lvl)) >> LVL_SHIFT(lvl);
>> + if (upper_bound)
>> + expires = expires >> LVL_SHIFT(lvl);
>> + else
>> + expires = (expires + LVL_GRAN(lvl)) >> LVL_SHIFT(lvl);
>
> While this "works", I fundamentally hate this because it adds an extra
> conditional into the common case. That affects every user of the timer
> wheel. We went great length to optimize that code and I'm not really enthused
> to sacrifice that just because of _one_ use case.

Aside of that this is not mathematically correct. Why?

The level selection makes the cutoff at: LEVEL_MAX(lvl) - 1. E.g. 62
instead of 63 for the first level.

The reason is that this accomodates for the + LVL_GRAN(lvl). Now with
surpressing the roundup this creates a gap. Not a horrible problem, but
not correct either.

Thanks,

tglx