On Thu, Oct 13, 2022 at 12:37 PM David Malcolm <dmalcolm@xxxxxxxxxx> wrote: > > Is it valid to apply the sparse attributes 'noderef' or 'address_space' > to non-pointers, and if so, what does this mean? It means that the thing itself is in said address space and cannot be accessed directly. IOW, if you have something like this (I'll just use "__percpu" as an example from the kernel): # define __percpu __attribute__((noderef, address_space(__percpu))) then int __percpu x; means that you cannot access the value of 'x' directly, and that x itself is in the "__percpu" address space. Trying to use the value of 'x', eg printf("%d\n", x); should cause a warning, along the lines of warning: dereference of noderef expression and taking the address of 'x' should result in a pointer that is of type int __percpu * which is entirely consistent (and then you'd have an inline function or macro that then does the right magic to dereference a pointer in that __percpu address space, in the kernel it would be "this_cpu_read()" and friends). > What is the intended meaning of "noderef" for a non-pointer? Note that the pointer use is the common (and historical) use in the kernel, but "noderef" really is not so much about the pointer, it's about what the pointer points to. IOW, notice that when you have a pointer to a __percpu variable, you don't mark the *pointer* as being __percpu. It's not "int *ptr __percpu", it's "int __percpu *ptr". (Ok, "int *ptr __percpu" does conceptually exist, but it means that the pointer itself is just an "int *", but it is in __percpu space, so it's not about how the pointer cannot be dereferenced - you cannot actually access the pointer value itself!). So the type system is entirely consistent. The documentation (and the naming) may be a bit pointer-centric, and that in turn comes from the historical use of this originally only being used for things like user pointers, but also from the fact that internally in sparse, accessing a variable is actually the same as dereferencing the symbol. Linus