I try to understand the smq policy and stumbled also about the logic/comment
in update_promote_levels(). Luckily there this recent post :)

>On Wed, Jun 17, 2026 at 10:23 AM <[email protected]> wrote:
>>
>> From: Cao Guanghui <[email protected]>
>>
>> In update_promote_levels(), the threshold_level is clamped against
>> NR_HOTSPOT_LEVELS (64) using max().  This is wrong: threshold_level is
>> later subtracted from NR_HOTSPOT_LEVELS to derive the actual promote
>> level, so a smaller threshold_level means a higher promote level (more
>> eager promotion).

I think this correct, but it reads a bit ambiguous - or it's just me. Anyway
I try to clarify:

should_promote() returns yes iff hs_e->level >= mq->read_promote_level

I.e. an entry in the hotspot queue needs a level above mq->read_promote_level
to be promoted. So a higher promote level sets a higher bar for promotion,
leading to a less eager promotion.
Or in other words:
  - smaller threshold == higher promote level == less eager promotion
  - higher threshold == lower promote level == more eager promotion

>> The comment above explicitly states that when the cache has unused
>> entries, "we want to be really eager to promote".  default_promote_level()
>> returns values in the range 1..8 for this case, which would produce a
>> promote level of 56..63 -- but max(threshold_level, 64) forces
>> threshold_level to 64, making the promote level 0 regardless of the
>> allocator state and defeating the eager-promotion logic entirely.

Yes, when using max(), the threshold_level does not depend on the allocator
state, so this is just a waste of CPU cycles. However it it does depend on
the hotspot_stats and may end up as 64, 32 or 16.

Using min() is also a waste of CPU cycles, because the initial value of
threshold_level is certainly smaller than NR_HOTSPOT_LEVELS (unless someone
messes up the defaults_promote_levels).

>Currently the promote_level could be {0, 32, 48}, depending on hotspot
>queue performance. Using min() instead would raise the promote_level
>to {32, 48, 56} when the cache is not full, or {56..63} when full,
>making the cache more conservative than the current setting in either
>case.

The promote_level is now 0 (WELL), 32 (FAIR) or 48 (POOR) for a non-full
cache or within {56..63} if the cache is filled entirely.
With min() this would be 32 (WELL), 48 (FAIR) or 56 (POOR). This is more
conservative.

BUT isn't this weird in the first place? Shouldn't a poorly performing
cache migrate more aggressively to increase the chance of cache hits?
And a well performing cache be conservative to maintain its good
performance?

>I noticed this ambiguity for a long time. A proper cleanup to remove
>default_promote_level() and simplify initialization is on my radar,
>but it's not urgent since the current behavior works.

Ok, what about just initialize threshold_level like this

threshold_level = allocator_empty(&mq->cache_alloc) ? 
                  default_promote_level(mq) : NR_HOTSPOT_LEVELS;

and remove the max/min line entirely. This does not change the current
behavior and spares some cycles?

   have a nice day
   stephan

Reply via email to