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).
>
> 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.

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.

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.


> Replace max() with min() so that threshold_level is properly capped at
> NR_HOTSPOT_LEVELS while still allowing small values to produce high
> promote levels as intended.
>
> Fixes: b29d4986d0da ("dm cache: significant rework to leverage 
> dm-bio-prison-v2")
> Signed-off-by: Cao Guanghui <[email protected]>
> ---
>  drivers/md/dm-cache-policy-smq.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/md/dm-cache-policy-smq.c 
> b/drivers/md/dm-cache-policy-smq.c
> index dd77a93fd68d..b3e5f7a12345 100644
> --- a/drivers/md/dm-cache-policy-smq.c
> +++ b/drivers/md/dm-cache-policy-smq.c
> @@ -1064,7 +1064,7 @@ static void update_promote_levels(struct smq_policy *mq)
>         unsigned int threshold_level = allocator_empty(&mq->cache_alloc) ?
>                 default_promote_level(mq) : (NR_HOTSPOT_LEVELS / 2u);
>
> -       threshold_level = max(threshold_level, NR_HOTSPOT_LEVELS);
> +       threshold_level = min(threshold_level, NR_HOTSPOT_LEVELS);
>
>         /*
>          * If the hotspot queue is performing badly then we have little
> --
> 2.25.1
>
>


Reply via email to