Thread (12 messages) 12 messages, 3 authors, 2022-05-06

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 Mikityanskiy
quoted
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)
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help