2007-10-16 08:35:39

by Remy Bohmer

[permalink] [raw]
Subject: [RT] seqlocks: use of PICK_FUNCTION breaks kernel compile when CONFIG_GENERIC_TIME is NOT set

Hello Daniel and Ingo,

I use 2.6.23-rt1 and the patch of Daniel below which seems to be in
there breaks the compilation of the RT-kernel when CONFIG_GENERIC_TIME
is NOT set.

It breaks in the do_gettimeofday(struct timeval *tv) code in the
architecture specific code
where there is a call to: seq = read_seqbegin_irqsave(&xtime_lock, flags);
The PICK_FUNCTION implementation does not return anything, so the
compile breaks here.

I am figuring out how to solve this problem nicely, but I have not
found a nice solution yet. Attached I have put my hack to make it
compile on ARM again, but maybe one of you can do a better proposal to
fix this.

Here is a list of files that will probably all fail to build: (I only
tested ARM)
linux-2.6.23/arch/arm/kernel/time.c:254
linux-2.6.23/arch/xtensa/kernel/time.c:132
linux-2.6.23/arch/sparc/kernel/time.c:453
linux-2.6.23/arch/sparc/kernel/pcic.c:776
linux-2.6.23/arch/blackfin/kernel/time.c:269
linux-2.6.23/arch/m68knommu/kernel/time.c:130
linux-2.6.23/arch/sh64/kernel/time.c:193
linux-2.6.23/arch/alpha/kernel/time.c:408
linux-2.6.23/arch/sh/kernel/time.c:65
linux-2.6.23/arch/m68k/kernel/time.c:104
linux-2.6.23/arch/ppc/kernel/time.c:207
linux-2.6.23/arch/s390/kernel/time.c:197


Kind Regards,

Remy Bohmer


2007/8/28, Daniel Walker <[email protected]>:
> Replace the old PICK_OP style macros with PICK_FUNCTION. Although,
> seqlocks has some alien code, which I also replaced as can be seen
> from the line count below.
>
> Signed-off-by: Daniel Walker <[email protected]>
>
> ---
> include/linux/pickop.h | 4
> include/linux/seqlock.h | 235 +++++++++++++++++++++++++++---------------------
> 2 files changed, 135 insertions(+), 104 deletions(-)
>
> Index: linux-2.6.22/include/linux/pickop.h
> ===================================================================
> --- linux-2.6.22.orig/include/linux/pickop.h
> +++ linux-2.6.22/include/linux/pickop.h
> @@ -1,10 +1,6 @@
> #ifndef _LINUX_PICKOP_H
> #define _LINUX_PICKOP_H
>
> -#undef TYPE_EQUAL
> -#define TYPE_EQUAL(var, type) \
> - __builtin_types_compatible_p(typeof(var), type *)
> -
> #undef PICK_TYPE_EQUAL
> #define PICK_TYPE_EQUAL(var, type) \
> __builtin_types_compatible_p(typeof(var), type)
> Index: linux-2.6.22/include/linux/seqlock.h
> ===================================================================
> --- linux-2.6.22.orig/include/linux/seqlock.h
> +++ linux-2.6.22/include/linux/seqlock.h
> @@ -90,6 +90,12 @@ static inline void __write_seqlock(seqlo
> smp_wmb();
> }
>
> +static __always_inline unsigned long __write_seqlock_irqsave(seqlock_t *sl)
> +{
> + __write_seqlock(sl);
> + return 0;
> +}
> +
> static inline void __write_sequnlock(seqlock_t *sl)
> {
> smp_wmb();
> @@ -97,6 +103,8 @@ static inline void __write_sequnlock(seq
> spin_unlock(&sl->lock);
> }
>
> +#define __write_sequnlock_irqrestore(sl, flags) __write_sequnlock(sl)
> +
> static inline int __write_tryseqlock(seqlock_t *sl)
> {
> int ret = spin_trylock(&sl->lock);
> @@ -149,6 +157,28 @@ static __always_inline void __write_seql
> smp_wmb();
> }
>
> +static __always_inline unsigned long
> +__write_seqlock_irqsave_raw(raw_seqlock_t *sl)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + __write_seqlock_raw(sl);
> + return flags;
> +}
> +
> +static __always_inline void __write_seqlock_irq_raw(raw_seqlock_t *sl)
> +{
> + local_irq_disable();
> + __write_seqlock_raw(sl);
> +}
> +
> +static __always_inline void __write_seqlock_bh_raw(raw_seqlock_t *sl)
> +{
> + local_bh_disable();
> + __write_seqlock_raw(sl);
> +}
> +
> static __always_inline void __write_sequnlock_raw(raw_seqlock_t *sl)
> {
> smp_wmb();
> @@ -156,6 +186,27 @@ static __always_inline void __write_sequ
> spin_unlock(&sl->lock);
> }
>
> +static __always_inline void
> +__write_sequnlock_irqrestore_raw(raw_seqlock_t *sl, unsigned long flags)
> +{
> + __write_sequnlock_raw(sl);
> + local_irq_restore(flags);
> + preempt_check_resched();
> +}
> +
> +static __always_inline void __write_sequnlock_irq_raw(raw_seqlock_t *sl)
> +{
> + __write_sequnlock_raw(sl);
> + local_irq_enable();
> + preempt_check_resched();
> +}
> +
> +static __always_inline void __write_sequnlock_bh_raw(raw_seqlock_t *sl)
> +{
> + __write_sequnlock_raw(sl);
> + local_bh_enable();
> +}
> +
> static __always_inline int __write_tryseqlock_raw(raw_seqlock_t *sl)
> {
> int ret = spin_trylock(&sl->lock);
> @@ -182,60 +233,93 @@ static __always_inline int __read_seqret
>
> extern int __bad_seqlock_type(void);
>
> -#define PICK_SEQOP(op, lock) \
> +/*
> + * PICK_SEQ_OP() is a small redirector to allow less typing of the lock
> + * types raw_seqlock_t, seqlock_t, at the front of the PICK_FUNCTION
> + * macro.
> + */
> +#define PICK_SEQ_OP(...) \
> + PICK_FUNCTION(raw_seqlock_t *, seqlock_t *, ##__VA_ARGS__)
> +#define PICK_SEQ_OP_RET(...) \
> + PICK_FUNCTION_RET(raw_seqlock_t *, seqlock_t *, ##__VA_ARGS__)
> +
> +#define write_seqlock(sl) PICK_SEQ_OP(__write_seqlock_raw, __write_seqlock, sl)
> +
> +#define write_sequnlock(sl) \
> + PICK_SEQ_OP(__write_sequnlock_raw, __write_sequnlock, sl)
> +
> +#define write_tryseqlock(sl) \
> + PICK_SEQ_OP_RET(__write_tryseqlock_raw, __write_tryseqlock, sl)
> +
> +#define read_seqbegin(sl) \
> + PICK_SEQ_OP_RET(__read_seqbegin_raw, __read_seqbegin, sl)
> +
> +#define read_seqretry(sl, iv) \
> + PICK_SEQ_OP_RET(__read_seqretry_raw, __read_seqretry, sl, iv)
> +
> +#define write_seqlock_irqsave(lock, flags) \
> do { \
> - if (TYPE_EQUAL((lock), raw_seqlock_t)) \
> - op##_raw((raw_seqlock_t *)(lock)); \
> - else if (TYPE_EQUAL((lock), seqlock_t)) \
> - op((seqlock_t *)(lock)); \
> - else __bad_seqlock_type(); \
> + flags = PICK_SEQ_OP_RET(__write_seqlock_irqsave_raw, \
> + __write_seqlock_irqsave, lock); \
> } while (0)
>
> -#define PICK_SEQOP_RET(op, lock) \
> -({ \
> - unsigned long __ret; \
> - \
> - if (TYPE_EQUAL((lock), raw_seqlock_t)) \
> - __ret = op##_raw((raw_seqlock_t *)(lock)); \
> - else if (TYPE_EQUAL((lock), seqlock_t)) \
> - __ret = op((seqlock_t *)(lock)); \
> - else __ret = __bad_seqlock_type(); \
> - \
> - __ret; \
> -})
> -
> -#define PICK_SEQOP_CONST_RET(op, lock) \
> -({ \
> - unsigned long __ret; \
> - \
> - if (TYPE_EQUAL((lock), raw_seqlock_t)) \
> - __ret = op##_raw((const raw_seqlock_t *)(lock));\
> - else if (TYPE_EQUAL((lock), seqlock_t)) \
> - __ret = op((seqlock_t *)(lock)); \
> - else __ret = __bad_seqlock_type(); \
> - \
> - __ret; \
> -})
> -
> -#define PICK_SEQOP2_CONST_RET(op, lock, arg) \
> - ({ \
> - unsigned long __ret; \
> - \
> - if (TYPE_EQUAL((lock), raw_seqlock_t)) \
> - __ret = op##_raw((const raw_seqlock_t *)(lock), (arg)); \
> - else if (TYPE_EQUAL((lock), seqlock_t)) \
> - __ret = op((seqlock_t *)(lock), (arg)); \
> - else __ret = __bad_seqlock_type(); \
> - \
> - __ret; \
> -})
> -
> -
> -#define write_seqlock(sl) PICK_SEQOP(__write_seqlock, sl)
> -#define write_sequnlock(sl) PICK_SEQOP(__write_sequnlock, sl)
> -#define write_tryseqlock(sl) PICK_SEQOP_RET(__write_tryseqlock, sl)
> -#define read_seqbegin(sl) PICK_SEQOP_CONST_RET(__read_seqbegin, sl)
> -#define read_seqretry(sl, iv) PICK_SEQOP2_CONST_RET(__read_seqretry, sl, iv)
> +#define write_seqlock_irq(lock) \
> + PICK_SEQ_OP(__write_seqlock_irq_raw, __write_seqlock, lock)
> +
> +#define write_seqlock_bh(lock) \
> + PICK_SEQ_OP(__write_seqlock_bh_raw, __write_seqlock, lock)
> +
> +#define write_sequnlock_irqrestore(lock, flags) \
> + PICK_SEQ_OP(__write_sequnlock_irqrestore_raw, \
> + __write_sequnlock_irqrestore, lock, flags)
> +
> +#define write_sequnlock_bh(lock) \
> + PICK_SEQ_OP(__write_sequnlock_bh_raw, __write_sequnlock, lock)
> +
> +#define write_sequnlock_irq(lock) \
> + PICK_SEQ_OP(__write_sequnlock_irq_raw, __write_sequnlock, lock)
> +
> +static __always_inline
> +unsigned long __read_seqbegin_irqsave_raw(raw_seqlock_t *sl)
> +{
> + unsigned long flags;
> +
> + local_irq_save(flags);
> + __read_seqbegin_raw(sl);
> + return flags;
> +}
> +
> +static __always_inline unsigned long __read_seqbegin_irqsave(seqlock_t *sl)
> +{
> + __read_seqbegin(sl);
> + return 0;
> +}
> +
> +#define read_seqbegin_irqsave(lock, flags) \
> +do { \
> + flags = PICK_SEQ_OP_RET(__read_seqbegin_irqsave_raw, \
> + __read_seqbegin_irqsave, lock); \
> +} while (0)
> +
> +static __always_inline int
> +__read_seqretry_irqrestore(seqlock_t *sl, unsigned iv, unsigned long flags)
> +{
> + return __read_seqretry(sl, iv);
> +}
> +
> +static __always_inline int
> +__read_seqretry_irqrestore_raw(raw_seqlock_t *sl, unsigned iv,
> + unsigned long flags)
> +{
> + int ret = read_seqretry(sl, iv);
> + local_irq_restore(flags);
> + preempt_check_resched();
> + return ret;
> +}
> +
> +#define read_seqretry_irqrestore(lock, iv, flags) \
> + PICK_SEQ_OP_RET(__read_seqretry_irqrestore_raw, \
> + __read_seqretry_irqrestore, lock, iv, flags)
>
> /*
> * Version using sequence counter only.
> @@ -286,53 +370,4 @@ static inline void write_seqcount_end(se
> smp_wmb();
> s->sequence++;
> }
> -
> -#define PICK_IRQOP(op, lock) \
> -do { \
> - if (TYPE_EQUAL((lock), raw_seqlock_t)) \
> - op(); \
> - else if (TYPE_EQUAL((lock), seqlock_t)) \
> - { /* nothing */ } \
> - else __bad_seqlock_type(); \
> -} while (0)
> -
> -#define PICK_IRQOP2(op, arg, lock) \
> -do { \
> - if (TYPE_EQUAL((lock), raw_seqlock_t)) \
> - op(arg); \
> - else if (TYPE_EQUAL(lock, seqlock_t)) \
> - { /* nothing */ } \
> - else __bad_seqlock_type(); \
> -} while (0)
> -
> -
> -
> -/*
> - * Possible sw/hw IRQ protected versions of the interfaces.
> - */
> -#define write_seqlock_irqsave(lock, flags) \
> - do { PICK_IRQOP2(local_irq_save, flags, lock); write_seqlock(lock); } while (0)
> -#define write_seqlock_irq(lock) \
> - do { PICK_IRQOP(local_irq_disable, lock); write_seqlock(lock); } while (0)
> -#define write_seqlock_bh(lock) \
> - do { PICK_IRQOP(local_bh_disable, lock); write_seqlock(lock); } while (0)
> -
> -#define write_sequnlock_irqrestore(lock, flags) \
> - do { write_sequnlock(lock); PICK_IRQOP2(local_irq_restore, flags, lock); preempt_check_resched(); } while(0)
> -#define write_sequnlock_irq(lock) \
> - do { write_sequnlock(lock); PICK_IRQOP(local_irq_enable, lock); preempt_check_resched(); } while(0)
> -#define write_sequnlock_bh(lock) \
> - do { write_sequnlock(lock); PICK_IRQOP(local_bh_enable, lock); } while(0)
> -
> -#define read_seqbegin_irqsave(lock, flags) \
> - ({ PICK_IRQOP2(local_irq_save, flags, lock); read_seqbegin(lock); })
> -
> -#define read_seqretry_irqrestore(lock, iv, flags) \
> - ({ \
> - int ret = read_seqretry(lock, iv); \
> - PICK_IRQOP2(local_irq_restore, flags, lock); \
> - preempt_check_resched(); \
> - ret; \
> - })
> -
> #endif /* __LINUX_SEQLOCK_H */
>
> --
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>


Attachments:
(No filename) (13.95 kB)
fix-compile-error-non-rt.patch (958.00 B)
Download all attachments

2007-10-16 16:54:44

by Daniel Walker

[permalink] [raw]
Subject: Re: [RT] seqlocks: use of PICK_FUNCTION breaks kernel compile when CONFIG_GENERIC_TIME is NOT set

On Tue, 2007-10-16 at 10:35 +0200, Remy Bohmer wrote:
> Hello Daniel and Ingo,
>
> I use 2.6.23-rt1 and the patch of Daniel below which seems to be in
> there breaks the compilation of the RT-kernel when CONFIG_GENERIC_TIME
> is NOT set.
>
> It breaks in the do_gettimeofday(struct timeval *tv) code in the
> architecture specific code
> where there is a call to: seq = read_seqbegin_irqsave(&xtime_lock, flags);
> The PICK_FUNCTION implementation does not return anything, so the
> compile breaks here.
>
> I am figuring out how to solve this problem nicely, but I have not
> found a nice solution yet. Attached I have put my hack to make it
> compile on ARM again, but maybe one of you can do a better proposal to
> fix this.

Here's another fix for this. I compile tested for ARM (!GENERIC_TIME) ,
but I didn't boot test .. Could you boot test this patch?

---

Move the read_seqbegin() call up in the chain so the value
can be returned

Signed-off-by: Daniel Walker <[email protected]>

---
include/linux/seqlock.h | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

Index: linux-2.6.23/include/linux/seqlock.h
===================================================================
--- linux-2.6.23.orig/include/linux/seqlock.h
+++ linux-2.6.23/include/linux/seqlock.h
@@ -285,21 +285,20 @@ unsigned long __read_seqbegin_irqsave_ra
unsigned long flags;

local_irq_save(flags);
- __read_seqbegin_raw(sl);
return flags;
}

static __always_inline unsigned long __read_seqbegin_irqsave(seqlock_t *sl)
{
- __read_seqbegin(sl);
return 0;
}

#define read_seqbegin_irqsave(lock, flags) \
-do { \
+({ \
flags = PICK_SEQ_OP_RET(__read_seqbegin_irqsave_raw, \
__read_seqbegin_irqsave, lock); \
-} while (0)
+ read_seqbegin(lock); \
+})

static __always_inline int
__read_seqretry_irqrestore(seqlock_t *sl, unsigned iv, unsigned long flags)


2007-10-17 14:07:45

by Remy Bohmer

[permalink] [raw]
Subject: Re: [RT] seqlocks: use of PICK_FUNCTION breaks kernel compile when CONFIG_GENERIC_TIME is NOT set

Hello Daniel,

> Here's another fix for this. I compile tested for ARM (!GENERIC_TIME) ,
> but I didn't boot test .. Could you boot test this patch?

This fix seems to work! The target still boots properly. So, it can be
pushed upstream... :-)

Kind Regards,

Remy Bohmer

2007/10/16, Daniel Walker <[email protected]>:
> On Tue, 2007-10-16 at 10:35 +0200, Remy Bohmer wrote:
> > Hello Daniel and Ingo,
> >
> > I use 2.6.23-rt1 and the patch of Daniel below which seems to be in
> > there breaks the compilation of the RT-kernel when CONFIG_GENERIC_TIME
> > is NOT set.
> >
> > It breaks in the do_gettimeofday(struct timeval *tv) code in the
> > architecture specific code
> > where there is a call to: seq = read_seqbegin_irqsave(&xtime_lock, flags);
> > The PICK_FUNCTION implementation does not return anything, so the
> > compile breaks here.
> >
> > I am figuring out how to solve this problem nicely, but I have not
> > found a nice solution yet. Attached I have put my hack to make it
> > compile on ARM again, but maybe one of you can do a better proposal to
> > fix this.
>
> Here's another fix for this. I compile tested for ARM (!GENERIC_TIME) ,
> but I didn't boot test .. Could you boot test this patch?
>
> ---
>
> Move the read_seqbegin() call up in the chain so the value
> can be returned
>
> Signed-off-by: Daniel Walker <[email protected]>
>
> ---
> include/linux/seqlock.h | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
> Index: linux-2.6.23/include/linux/seqlock.h
> ===================================================================
> --- linux-2.6.23.orig/include/linux/seqlock.h
> +++ linux-2.6.23/include/linux/seqlock.h
> @@ -285,21 +285,20 @@ unsigned long __read_seqbegin_irqsave_ra
> unsigned long flags;
>
> local_irq_save(flags);
> - __read_seqbegin_raw(sl);
> return flags;
> }
>
> static __always_inline unsigned long __read_seqbegin_irqsave(seqlock_t *sl)
> {
> - __read_seqbegin(sl);
> return 0;
> }
>
> #define read_seqbegin_irqsave(lock, flags) \
> -do { \
> +({ \
> flags = PICK_SEQ_OP_RET(__read_seqbegin_irqsave_raw, \
> __read_seqbegin_irqsave, lock); \
> -} while (0)
> + read_seqbegin(lock); \
> +})
>
> static __always_inline int
> __read_seqretry_irqrestore(seqlock_t *sl, unsigned iv, unsigned long flags)
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

2007-10-17 15:12:20

by Steven Rostedt

[permalink] [raw]
Subject: Re: [RT] seqlocks: use of PICK_FUNCTION breaks kernel compile when CONFIG_GENERIC_TIME is NOT set

On Wed, 2007-10-17 at 07:48 -0700, Daniel Walker wrote:
> Steven,
>
> Could you include this patch, it was submitted on the list but you
> didn't get CC'd ..

Thanks, it may have been a while before I see this (/me has been nose
deep in debugging).

> > On Tue, 2007-10-16 at 10:35 +0200, Remy Bohmer wrote:
> > > Hello Daniel and Ingo,
> > >
> > > I use 2.6.23-rt1 and the patch of Daniel below which seems to be in
> > > there breaks the compilation of the RT-kernel when CONFIG_GENERIC_TIME
> > > is NOT set.
> > >
> > > It breaks in the do_gettimeofday(struct timeval *tv) code in the
> > > architecture specific code
> > > where there is a call to: seq = read_seqbegin_irqsave(&xtime_lock, flags);
> > > The PICK_FUNCTION implementation does not return anything, so the
> > > compile breaks here.
> > >
> > > I am figuring out how to solve this problem nicely, but I have not
> > > found a nice solution yet. Attached I have put my hack to make it
> > > compile on ARM again, but maybe one of you can do a better proposal to
> > > fix this.
> >
> > Here's another fix for this. I compile tested for ARM (!GENERIC_TIME) ,
> > but I didn't boot test .. Could you boot test this patch?
> >
> > ---
> >
> > Move the read_seqbegin() call up in the chain so the value
> > can be returned
> >
> > Signed-off-by: Daniel Walker <[email protected]>
> >
> > ---
> > include/linux/seqlock.h | 7 +++----
> > 1 file changed, 3 insertions(+), 4 deletions(-)
> >
> > Index: linux-2.6.23/include/linux/seqlock.h
> > ===================================================================
> > --- linux-2.6.23.orig/include/linux/seqlock.h
> > +++ linux-2.6.23/include/linux/seqlock.h
> > @@ -285,21 +285,20 @@ unsigned long __read_seqbegin_irqsave_ra
> > unsigned long flags;
> >
> > local_irq_save(flags);
> > - __read_seqbegin_raw(sl);
> > return flags;
> > }
> >
> > static __always_inline unsigned long __read_seqbegin_irqsave(seqlock_t *sl)
> > {
> > - __read_seqbegin(sl);
> > return 0;
> > }

The above should be renamed. They have nothing to do with seqlocks now.

> >
> > #define read_seqbegin_irqsave(lock, flags) \
> > -do { \
> > +({ \
> > flags = PICK_SEQ_OP_RET(__read_seqbegin_irqsave_raw, \
> > __read_seqbegin_irqsave, lock); \
> > -} while (0)
> > + read_seqbegin(lock); \
> > +})

Yes, definitely the raw and unraw functions should be called
local_irqsave_raw or something else that makes this obvious to what it
is doing.

-- Steve


2007-10-17 15:26:22

by Daniel Walker

[permalink] [raw]
Subject: Re: [RT] seqlocks: use of PICK_FUNCTION breaks kernel compile when CONFIG_GENERIC_TIME is NOT set

On Wed, 2007-10-17 at 11:10 -0400, Steven Rostedt wrote:

> > >
> > > #define read_seqbegin_irqsave(lock, flags) \
> > > -do { \
> > > +({ \
> > > flags = PICK_SEQ_OP_RET(__read_seqbegin_irqsave_raw, \
> > > __read_seqbegin_irqsave, lock); \
> > > -} while (0)
> > > + read_seqbegin(lock); \
> > > +})
>
> Yes, definitely the raw and unraw functions should be called
> local_irqsave_raw or something else that makes this obvious to what it
> is doing.

Hmm.. I'm not sure what else to name them .. Since it's in the seqlock.h
I don't think it should be called anything "local_irq*" .. It could be
seq_irqsave_{raw} .

Daniel

2007-10-17 15:35:37

by Steven Rostedt

[permalink] [raw]
Subject: Re: [RT] seqlocks: use of PICK_FUNCTION breaks kernel compile when CONFIG_GENERIC_TIME is NOT set


--

On Wed, 17 Oct 2007, Daniel Walker wrote:

> On Wed, 2007-10-17 at 11:10 -0400, Steven Rostedt wrote:
>
> > > >
> > > > #define read_seqbegin_irqsave(lock, flags) \
> > > > -do { \
> > > > +({ \
> > > > flags = PICK_SEQ_OP_RET(__read_seqbegin_irqsave_raw, \
> > > > __read_seqbegin_irqsave, lock); \
> > > > -} while (0)
> > > > + read_seqbegin(lock); \
> > > > +})
> >
> > Yes, definitely the raw and unraw functions should be called
> > local_irqsave_raw or something else that makes this obvious to what it
> > is doing.
>
> Hmm.. I'm not sure what else to name them .. Since it's in the seqlock.h
> I don't think it should be called anything "local_irq*" .. It could be
> seq_irqsave_{raw} .

Hmm, what about a __seq_irqsave_raw and __seq_nop?

That way it spells out that irqs are NOT touched if it is not a raw lock.

-- Steve

2007-10-22 18:56:29

by Daniel Walker

[permalink] [raw]
Subject: Re: [RT] seqlocks: use of PICK_FUNCTION breaks kernel compile when CONFIG_GENERIC_TIME is NOT set

On Wed, 2007-10-17 at 11:34 -0400, Steven Rostedt wrote:

>
> Hmm, what about a __seq_irqsave_raw and __seq_nop?
>
> That way it spells out that irqs are NOT touched if it is not a raw lock.

I took out the nop , and just did a save flags which makes sense.. There
is still more cleanup to do in that regard.

Signed-off-by: Daniel Walker <[email protected]>

---
include/linux/seqlock.h | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)

Index: linux-2.6.23/include/linux/seqlock.h
===================================================================
--- linux-2.6.23.orig/include/linux/seqlock.h
+++ linux-2.6.23/include/linux/seqlock.h
@@ -92,8 +92,11 @@ static inline void __write_seqlock(seqlo

static __always_inline unsigned long __write_seqlock_irqsave(seqlock_t *sl)
{
+ unsigned long flags;
+
+ local_save_flags(flags);
__write_seqlock(sl);
- return 0;
+ return flags;
}

static inline void __write_sequnlock(seqlock_t *sl)
@@ -280,26 +283,27 @@ do { \
PICK_SEQ_OP(__write_sequnlock_irq_raw, __write_sequnlock, lock)

static __always_inline
-unsigned long __read_seqbegin_irqsave_raw(raw_seqlock_t *sl)
+unsigned long __seq_irqsave_raw(raw_seqlock_t *sl)
{
unsigned long flags;

local_irq_save(flags);
- __read_seqbegin_raw(sl);
return flags;
}

-static __always_inline unsigned long __read_seqbegin_irqsave(seqlock_t *sl)
+static __always_inline unsigned long __seq_irqsave(seqlock_t *sl)
{
- __read_seqbegin(sl);
- return 0;
+ unsigned long flags;
+
+ local_save_flags(flags);
+ return flags;
}

-#define read_seqbegin_irqsave(lock, flags) \
-do { \
- flags = PICK_SEQ_OP_RET(__read_seqbegin_irqsave_raw, \
- __read_seqbegin_irqsave, lock); \
-} while (0)
+#define read_seqbegin_irqsave(lock, flags) \
+({ \
+ flags = PICK_SEQ_OP_RET(__seq_irqsave_raw, __seq_irqsave, lock);\
+ read_seqbegin(lock); \
+})

static __always_inline int
__read_seqretry_irqrestore(seqlock_t *sl, unsigned iv, unsigned long flags)