On Mon, Sep 16 2024 at 15:20, Costa Shulyupin wrote: > +/* > + * housekeeping_update - change housekeeping.cpumasks[type] and propagate the > + * change. > + */ > +static int housekeeping_update(enum hk_type type, const struct cpumask *update) > +{ > + struct { > + struct cpumask changed; > + struct cpumask enable; > + struct cpumask disable; > + } *masks; > + > + masks = kmalloc(sizeof(*masks), GFP_KERNEL); > + if (!masks) > + return -ENOMEM; > + > + lockdep_assert_cpus_held(); > + cpumask_xor(&masks->changed, housekeeping_cpumask(type), update); > + cpumask_and(&masks->enable, &masks->changed, update); > + cpumask_andnot(&masks->disable, &masks->changed, update); > + cpumask_copy(housekeeping.cpumasks[type], update); > + WRITE_ONCE(housekeeping.flags, housekeeping.flags | BIT(type)); So this sets the bit for the type > + if (!static_branch_unlikely(&housekeeping_overridden)) > + static_key_enable_cpuslocked(&housekeeping_overridden.key); What's the point of doing this on every iteration? > + kfree(masks); > + > + return 0; > +} > + > static int __init housekeeping_setup(char *str, unsigned long flags) > { > cpumask_var_t non_housekeeping_mask, housekeeping_staging; > @@ -327,8 +357,11 @@ int housekeeping_exlude_isolcpus(const struct cpumask *isolcpus, unsigned long f > /* > * Reset housekeeping to bootup default > */ > + > + for_each_clear_bit(type, &boot_hk_flags, HK_TYPE_MAX) > + housekeeping_update(type, cpu_possible_mask); Even for those which are clear > for_each_set_bit(type, &boot_hk_flags, HK_TYPE_MAX) > - cpumask_copy(housekeeping.cpumasks[type], boot_hk_cpumask); > + housekeeping_update(type, boot_hk_cpumask); > > WRITE_ONCE(housekeeping.flags, boot_hk_flags); Just to overwrite them with boot_hk_flags afterwards. That does not make any sense at all. Thanks, tglx