Re: [PATCH net-next] tls: Add opt-in zerocopy mode of sendfile()
From: Maxim Mikityanskiy <hidden>
Date: 2022-05-05 18:34:41
On 2022-05-05 16:48, David Laight wrote:
From: Maxim Mikityanskiyquoted
Sent: 05 May 2022 13:40 On 2022-05-04 12:49, David Laight wrote:quoted
quoted
quoted
If you declare the union on the stack in the callers, and pass by value - is the compiler not going to be clever enough to still DDRT?Ah, OK, it should do the thing. I thought you wanted me to ditch the union altogether.Some architectures always pass struct/union by address. Which is probably not what you had in mind.Do you have any specific architecture in mind? I couldn't find any information that it happens anywhere, x86_64 ABI [1] (pages 20-21) aligns with my expectations, and my common sense can't explain why would some architectures do what you say. In C, when the caller passes a struct as a parameter, the callee can freely modify it. If the compiler silently replaced it with a pointer, the callee would corrupt the caller's local variable, so such approach requires the caller to make an extra copy.Yes, that is what happens.
I did a quick experiment with gcc 9 on m68k and i386, and it doesn't
confirm what you claim.
#include <stdint.h>
#include <stdio.h>
union test {
uint32_t x;
uint32_t *y;
};
void func1(void *ptr, union test t)
{
if (ptr) {
printf("%p %u\n", ptr, t.x);
} else {
printf("%u\n", *t.y);
}
}
void func2(void *ptr, uint32_t *y)
{
if (ptr) {
printf("%p %u\n", ptr, (uint32_t)y);
} else {
printf("%u\n", *y);
}
}
gcc -S test.c -fno-strict-aliasing -o -
I believe this minimal example reflects well enough what happens in my
code. The assembly generated for func1 and func2 are identical. In both
cases the second parameter is passed on the stack by value, not by pointer.
quoted
Making an extra copy on the stack and passing a pointer doesn't make any sense to me if you can just make a copy on the stack (or to a register) and call it a parameter. If you know any specific architecture supported by Linux that passes all unions by a pointer, could you please point me to it? Maybe I'm missing something in my logic, and a real-world example will explain things, but at the moment it sounds unrealistic to me.Look at any old architecture, m68k almost certainly passes all structures by address. i386 would - but I think the 'regparm' option includes passing small structures by value.
i386 passes all parameters on the stack by default, and regparm makes some parameters be passed in registers instead of the stack, but it doesn't have any other weird effects. The value passed is the same in both cases, the only difference is registers vs stack.
I think sparc32 used to, but that might have changed in the last 30 years. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)