Re: [RFC PATCH v2 0/5] allow overriding default preempt mode from command line

Peter Zijlstra
2020-10-27T12:28:51Z

On Tue, Oct 27, 2020 at 01:22:41PM +0100, Frederic Weisbecker wrote:
> On Fri, Oct 09, 2020 at 07:45:54PM +0200, Peter Zijlstra wrote:
> > +DEFINE_STATIC_KEY_TRUE(irq_preemption_key);
> > +
> > +/*
> > + * SC:cond_resched
> > + * SC:might_resched
> > + * SC:preempt_schedule
> > + * SC:preempt_schedule_notrace
> > + * SB:irq_preemption_key
> > + *
> > + *
> > + * ZERO
> > + * cond_resched <- RET0
> > + * might_resched <- NOP
> > + * preempt_schedule <- NOP
> > + * preempt_schedule_notrace <- NOP
> > + * irq_preemption_key <- false
> > + *
> > + * NONE:
> > + * cond_resched <- __cond_resched
> > + * might_resched <- NOP
> > + * preempt_schedule <- NOP
> > + * preempt_schedule_notrace <- NOP
> > + * irq_preemption_key <- false
> > + *
> > + * VOLUNTARY:
> > + * cond_resched <- __cond_resched
> > + * might_resched <- __might_resched
> > + * preempt_schedule <- NOP
> > + * preempt_schedule_notrace <- NOP
> > + * irq_preemption_key <- false
> > + *
> > + * FULL:
> > + * cond_resched <- RET0
> > + * might_resched <- NOP
> > + * preempt_schedule <- preempt_schedule
> > + * preempt_schedule_notrace <- preempt_schedule_notrace
> > + * irq_preemption_key <- true
> > + */
>
> That's cute! I'll try to end up to that result.

Beware, ZERO is 'broken', I included it because I was curious what, if
anything, would happen :-)

> > +static int __init setup_preempt_mode(char *str)
> > +{
> > + if (!strcmp(str, "zero")) {
> > + static_call_update(cond_resched, __static_call_return0);
> > + static_call_update(might_resched, (void (*)(void))NULL);
> > + static_call_update(preempt_schedule, (void (*)(void))NULL);
> > + static_call_update(preempt_schedule_notrace, (void (*)(void))NULL);
> > + static_branch_disable(&irq_preemption_key);
> > + printk("XXX PREEMPT: %s\n", str);
> > + } else if (!strcmp(str, "none")) {
> > + static_call_update(cond_resched, __cond_resched);
> > + static_call_update(might_resched, (void (*)(void))NULL);
> > + static_call_update(preempt_schedule, (void (*)(void))NULL);
> > + static_call_update(preempt_schedule_notrace, (void (*)(void))NULL);
> > + static_branch_disable(&irq_preemption_key);
> > + printk("XXX PREEMPT: %s\n", str);
> > + } else if (!strcmp(str, "voluntary")) {
> > + static_call_update(cond_resched, __cond_resched);
> > + static_call_update(might_resched, __might_resched);
> > + static_call_update(preempt_schedule, (void (*)(void))NULL);
> > + static_call_update(preempt_schedule_notrace, (void (*)(void))NULL);
> > + static_branch_disable(&irq_preemption_key);
> > + printk("XXX PREEMPT: %s\n", str);
> > + } else if (!strcmp(str, "ponies")) {
> > + static_call_update(cond_resched, __cond_resched);
> > + static_call_update(might_resched, (void (*)(void))NULL);
> > + static_call_update(preempt_schedule, preempt_schedule_thunk);
> > + static_call_update(preempt_schedule_notrace, preempt_schedule_notrace_thunk);
> > + static_branch_enable(&irq_preemption_key);
> > + printk("XXX PREEMPT: %s\n", str);
>
> Why would we need that ponies version?

We don't, but it was a missing combination (like ZERO), and I wanted to
test it worked (as expected, it does).

We'll only encounter it as an intermediate state when flipping states at
runtime, but unlike zero, it should work just fine.