Messages in this thread | | | From | Andy Lutomirski <> | Date | Tue, 21 Jul 2015 08:51:51 -0700 | Subject | Re: Kernel broken on processors without performance counters |
| |
On Tue, Jul 21, 2015 at 8:49 AM, Peter Zijlstra <peterz@infradead.org> wrote: > On Tue, Jul 21, 2015 at 05:43:27PM +0200, Thomas Gleixner wrote: >> On Tue, 21 Jul 2015, Peter Zijlstra wrote: >> >> > > -#endif /* _LINUX_JUMP_LABEL_H */ >> > > +static inline void static_key_enable(struct static_key *key) >> > > +{ >> > > + int count = static_key_count(key); >> > > + >> > > + WARN_ON_ONCE(count < 0 || count > 1); >> > > + >> > > + if (!count) >> > > + static_key_slow_inc(key); >> > > +} >> > > + >> > > +static inline void static_key_disable(struct static_key *key) >> > > +{ >> > > + int count = static_key_count(key); >> > > + >> > > + WARN_ON_ONCE(count < 0 || count > 1); >> > > + >> > > + if (count) >> > > + static_key_slow_dec(key); >> > > +} >> >> The functions above are not part of the interface which should be used >> in code, right? > > They are in fact. They make it easier to deal with the refcount thing > when all you want is boolean states. > >> > > +/* -------------------------------------------------------------------------- */ >> > > + >> > > +/* >> > > + * likely -- default enabled, puts the branch body in-line >> > > + */ >> > > + >> > > +struct static_likely_key { >> > > + struct static_key key; >> > > +}; >> > > + >> > > +#define STATIC_LIKELY_KEY_INIT (struct static_likely_key){ .key = STATIC_KEY_INIT_TRUE, } >> > > + >> > > +static inline bool static_likely_branch(struct static_likely_key *key) >> > > +{ >> > > + return static_key_true(&key->key); >> > > +} >> > > + >> > > +/* >> > > + * unlikely -- default disabled, puts the branch body out-of-line >> > > + */ >> > > + >> > > +struct static_unlikely_key { >> > > + struct static_key key; >> > > +}; >> > > + >> > > +#define STATIC_UNLIKELY_KEY_INIT (struct static_unlikely_key){ .key = STATIC_KEY_INIT_FALSE, } >> > > + >> > > +static inline bool static_unlikely_branch(struct static_unlikely_key *key) >> > > +{ >> > > + return static_key_false(&key->key); >> > > +} >> > > + >> > > +/* >> > > + * Advanced usage; refcount, branch is enabled when: count != 0 >> > > + */ >> > > + >> > > +#define static_branch_inc(_k) static_key_slow_inc(&(_k)->key) >> > > +#define static_branch_dec(_k) static_key_slow_dec(&(_k)->key) >> >> Inlines please >> >> > > +/* >> > > + * Normal usage; boolean enable/disable. >> > > + */ >> > > + >> > > +#define static_branch_enable(_k) static_key_enable(&(_k)->key) >> > > +#define static_branch_disable(_k) static_key_disable(&(_k)->key) >> >> Ditto >> >> All in all much more understandable than the existing horror. > > They cannot in fact be inlines because we play type tricks. Note how _k > can be either struct static_likely_key or struct static_unlikely_key. > >
To clarify my (mis-)understanding:
There are two degrees of freedom in a static_key. They can start out true or false, and they can be unlikely or likely. Are those two degrees of freedom in fact tied together?
--Andy
| |