On Wed, Jul 08, 2020 at 02:29:38PM +0200, Peter Zijlstra wrote:
> On Wed, Jul 08, 2020 at 12:33:14PM +0200, Ahmed S. Darwish wrote:
>
> > > +#define read_seqcount_begin(s)   
> > > do_read_seqcount_begin(__to_seqcount_t(s))
> > > +
> > > +static inline unsigned do_read_seqcount_begin(const seqcount_t *s)
> > > +{
> > ...
> >
> > Hmm, the __to_seqcount_t(s) force cast is not good. It will break the
> > arguments type-safety of seqcount macros that do not have either:
> >
> >     __associated_lock_is_preemptible() or
> >     __assert_associated_lock_held()
> >
> > in their path. This basically includes all the read path macros, and
> > even some others (e.g. write_seqcount_invalidate()).
> >
> > With the suggested force cast above, I can literally *pass anything* to
> > read_seqcount_begin() and friends, and the compiler won't say a thing.
> >
> > So, I'll restore __to_seqcount_t(s) that to its original implementation:
>
> Right, I figured that the write side would be enough to catch glaring
> abuse. But sure.
>
> It's a bummer we didn't upgrade the minimum compiler version to 4.9,
> that would've given us _Generic(), which allows one to write this
> slightly less verbose I think.
>

Looking at 5429ef62bcf3 ("compiler/gcc: Raise minimum GCC version for
kernel builds to 4.8"), it seems that the decision of picking gcc 4.8
vs. 4.9 was kinda arbitrary.

Anyway, please continue below.

> How about something disguisting like this then?
>
...
> #define __SEQ_RT      IS_BUILTIN(CONFIG_PREEMPT_RT)
>
> SEQCOUNT_LOCKTYPE(raw_spinlock, raw_spinlock_t,       false,          lock)
> SEQCOUNT_LOCKTYPE(spinlock,   spinlock_t,             __SEQ_RT,       lock)
> SEQCOUNT_LOCKTYPE(rwlock,     rwlock_t,               __SEQ_RT,       lock)
> SEQCOUNT_LOCKTYPE(mutex,      struct mutex,           true,           lock)
> SEQCOUNT_LOCKTYPE(ww_mutex,   struct ww_mutex,        true,           
> lock->base)
>
> #if (defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 40900) || 
> defined(__CHECKER__)
>
> #define __seqprop_pick(const_expr, s, locktype, prop, otherwise)      \
>       __builtin_choose_expr(const_expr,                               \
>                             __seqprop_##locktype##_##prop((void *)(s)), \
>                             otherwise)
>
> extern void __seqprop_invalid(void);
>
> #define __seqprop(s, prop)                                                    
>         \
>       __seqprop_pick(__same_type(*(s), seqcount_t), (s), seqcount, prop,      
>         \
>         __seqprop_pick(__same_type(*(s), seqcount_raw_spinlock_t), (s), 
> raw_spinlock, prop, \
>           __seqprop_pick(__same_type(*(s), seqcount_spinlock_t), (s), 
> spinlock, prop, \
>             __seqprop_pick(__same_type(*(s), seqcount_rwlock_t), (s), rwlock, 
> prop,   \
>               __seqprop_pick(__same_type(*(s), seqcount_mutex_t), (s), mutex, 
> prop,   \
>                 __seqprop_pick(__same_type(*(s), seqcount_ww_mutex_t), (s), 
> ww_mutex, prop, \
>                   __seqprop_invalid()))))))
>
> #else
>
> #define __seqprop_case(s, locktype, prop) \
>       seqcount_##locktype##_t: __seqprop_##locktype##_##prop((void *)s)
>
> #define __seqprop(s, prop)                                    \
>       _Generic(*(s),                                          \
>                seqcount_t: __seqprop_seqcount_##prop((void*)s),\
>                __seqprop_case((s), raw_spinlock, prop),       \
>                __seqprop_case((s), spinlock, prop),           \
>                __seqprop_case((s), rwlock, prop),             \
>                __seqprop_case((s), mutex, prop),              \
>                __seqprop_case((s), ww_mutex, prop))
>
> #endif
>
> #define __to_seqcount_t(s)                    __seqprop(s, ptr)
> #define __associated_lock_is_preemptible(s)   __seqprop(s, preempt)
> #define __assert_associated_lock_held(s)      __seqprop(s, assert)

Hmm, I'll prototype the whole thing (along with PREEMPT_RT associated
lock()/unlock() as you've mentioned in the other e-mail), and come back.

Honestly, I have a first impression that this is heading into too much
complexity and compaction, but let's finish the whole thing first.

Thanks,

--
Ahmed S. Darwish
Linutronix GmbH

Reply via email to