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
