linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: Uros Bizjak <ubizjak@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	kernel test robot <lkp@intel.com>,
	oe-kbuild-all@lists.linux.dev, linux-kernel@vger.kernel.org,
	Arjan van de Ven <arjan@linux.intel.com>,
	x86@kernel.org, Luc Van Oostenryck <luc.vanoostenryck@gmail.com>,
	Sparse Mailing-list <linux-sparse@vger.kernel.org>,
	"Paul E. McKenney" <paulmck@kernel.org>
Subject: Re: arch/x86/include/asm/processor.h:698:16: sparse: sparse: incorrect type in initializer (different address spaces)
Date: Mon, 04 Mar 2024 00:49:18 +0100	[thread overview]
Message-ID: <87bk7ux4e9.ffs@tglx> (raw)
In-Reply-To: <CAFULd4b0HN6eUJsOW6po8Hf16T3eMhjdKUvw-TS8yncNn-+Vyw@mail.gmail.com>

On Sun, Mar 03 2024 at 21:24, Uros Bizjak wrote:
> On Sun, Mar 3, 2024 at 9:21 PM Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Sun, Mar 3, 2024 at 9:10 PM Thomas Gleixner <tglx@linutronix.de> wrote:
>> > That's so sad because it would provide us compiler based __percpu
>> > validation.
>>
>> Unfortunately, the c compiler can't strip qualifiers, so typeof() is
>> of limited use also when const and volatile qualifiers are used.
>> Perhaps some extension could be introduced to c standard to provide an
>> unqualified type, e.g. typeof_unqual().
>
> Oh, there is one in C23 [1].

Yes. I found it right after ranting.

gcc >= 14 and clang >= 16 have support for it of course only when adding
-std=c2x to the command line.

Sigh. The name space qualifiers are non standard and then the thing
which makes them more useful is hidden behind a standard.

Why can't we have useful tools?

Though the whole thing looks worthwhile:

#define verify_per_cpu_ptr(ptr)						\
do {									\
	const void __seg_gs *__vpp_verify = (typeof((ptr) + 0))NULL;    \
	(void)__vpp_verify;						\
} while (0)

#define per_cpu_ptr(ptr, cpu)						\
({									\
	verify_per_cpu_ptr(ptr);					\
	(typeof_unqual(*(ptr)) *)(uintptr_t)ptr + per_cpu_offset(cpu);	\
})

unsigned int __seg_gs test;

unsigned int foo1(unsigned int cpu)
{
	return *per_cpu_ptr(&test, cpu);
}

unsigned int foo2(unsigned int cpu)
{
	unsigned int x, *p = per_cpu_ptr(&x, cpu);

	return *p;
}

x.c:29:23: error: initializing 'const __attribute__((address_space(256))) void *' with an expression of type 'typeof ((&x) + 0)' (aka 'unsigned int *') changes address space of pointer
        unsigned int x, *p = per_cpu_ptr(&x, cpu);

That's exactly what we want. It would have caught all the long standing
and ignored __percpu sparse warnings right away.

This also simplifies all the other per cpu accessors. The most trivial
is read()

#define verify_per_cpu(variable)					\
{									\
	const unsigned int __s = sizeof(variable);			\
									\
	verify_per_cpu_ptr(&(variable));				\
	BUILD_BUG_ON(__s == 1 || __s == 2 || __s == 4 || __s == 8,	\
		     "Wrong size for per CPU variable");		\
}

#define __pcpu_read(variable)						\
({									\
	verify_per_cpu(variable);					\
	READ_ONCE(variable);						\
})

which in turn catches all the mistakes, i.e. wrong namespace and wrong
size.

I'm really tempted to implement this as an alternative to the current
pile of macro horrors. Of course this requires to figure out first what
kind of damage -std=c2x will do.

I get to that in my copious spare time some day.

Thanks,

        tglx

  parent reply	other threads:[~2024-03-03 23:49 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <202403020457.RCJoQ3ts-lkp@intel.com>
     [not found] ` <87edctwr6y.ffs@tglx>
     [not found]   ` <87a5nhwpus.ffs@tglx>
     [not found]     ` <87y1b0vp8m.ffs@tglx>
2024-03-02 15:44       ` arch/x86/include/asm/processor.h:698:16: sparse: sparse: incorrect type in initializer (different address spaces) Thomas Gleixner
2024-03-02 22:00         ` Thomas Gleixner
2024-03-02 22:49           ` Linus Torvalds
2024-03-03 16:31             ` Thomas Gleixner
2024-03-03 19:03               ` Uros Bizjak
2024-03-03 20:10                 ` Thomas Gleixner
2024-03-03 20:21                   ` Uros Bizjak
2024-03-03 20:24                     ` Uros Bizjak
2024-03-03 21:19                       ` Uros Bizjak
2024-03-03 23:49                       ` Thomas Gleixner [this message]
2024-03-04  5:42                         ` Uros Bizjak
2024-03-04  7:07                           ` Thomas Gleixner
2024-04-02 11:43                             ` Uros Bizjak
2024-04-03 17:57                               ` Nathan Chancellor
2024-04-04  6:56                                 ` Uros Bizjak
2024-04-29 21:30                         ` [RFC PATCH] Use x86 named address spaces to catch "sparse: incorrect type in initializer (different address spaces)" __percpu errors Uros Bizjak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87bk7ux4e9.ffs@tglx \
    --to=tglx@linutronix.de \
    --cc=arjan@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sparse@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=luc.vanoostenryck@gmail.com \
    --cc=oe-kbuild-all@lists.linux.dev \
    --cc=paulmck@kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=ubizjak@gmail.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).