From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexei Starovoitov Subject: Re: [PATCH 1/6] perf: Add new type PERF_TYPE_PROBE Date: Sat, 25 Nov 2017 17:59:54 -0800 Message-ID: <11e688f0-c1bc-8925-225a-5b8e795336c7@fb.com> References: <20171115172339.1791161-1-songliubraving@fb.com> <20171115172339.1791161-3-songliubraving@fb.com> <20171123100214.qm3s4h5b6i4r2iaa@hirez.programming.kicks-ass.net> <20171124082827.nvgr3bfu3bidfdjx@hirez.programming.kicks-ass.net> Mime-Version: 1.0 Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit Cc: Song Liu , , , , , , , To: Peter Zijlstra Return-path: In-Reply-To: <20171124082827.nvgr3bfu3bidfdjx@hirez.programming.kicks-ass.net> Sender: linux-kernel-owner@vger.kernel.org List-Id: netdev.vger.kernel.org On 11/24/17 12:28 AM, Peter Zijlstra wrote: > On Thu, Nov 23, 2017 at 10:31:29PM -0800, Alexei Starovoitov wrote: >> unfortunately 32-bit is more screwed than it seems: >> >> $ cat align.c >> #include >> >> struct S { >> unsigned long long a; >> } s; >> >> struct U { >> unsigned long long a; >> } u; >> >> int main() >> { >> printf("%d, %d\n", sizeof(unsigned long long), >> __alignof__(unsigned long long)); >> printf("%d, %d\n", sizeof(s), __alignof__(s)); >> printf("%d, %d\n", sizeof(u), __alignof__(u)); >> } >> $ gcc -m32 align.c >> $ ./a.out >> 8, 8 >> 8, 4 >> 8, 4 > > *blink* how is that even correct? I understood the spec to say the > alignment of composite types should be the max alignment of any of its > member types (otherwise it cannot guarantee the alignment of its > members). > >> so we have to use __aligned_u64 in uapi. > > Ideally yes, but effectively it most often doesn't matter. > >> Otherwise, yes, we could have used config1 and config2 to pass pointers >> to the kernel, but since they're defined as __u64 already we cannot >> change them and have to do this ugly dance around 'config' field. > > I don't understand the reasoning why you cannot use them. Even if they > are not naturally aligned on x86_32, why would it matter? > > x86_32 needs two loads in any case, but there is no concurrency, so > split loads is not a problem. Add to that that 'intptr_t' on ILP32 > is in fact only a single u32 and thus the other u32 will always be 0. > > So yes, alignment is screwy, but I really don't see who cares and why it > would matter in practise. If we were poking into 'struct perf_event_attr __user *uptr' directly like get|put_user(.., &uptr->config) then 32-bit user space with 4-byte aligned u64s would cause 64-bit kernel to trap on archs like sparc. But in this case you're right. We can use config[12] as-is, since these u64 fields are passing the value one way only (into the kernel) and we do full perf_copy_attr() first and all further accesses are from copied structure and u64_to_user_ptr(event->attr.config) will be fine. Do you mind we do union { __u64 file_path; __u64 func_name; __u64 config; }; and similar with config1 ? Or prefer that we use 'config/config1' to store string+offset there? I think config/config1 is cleaner than config1/config2