[v3,2/2] posix: Implement preadv2 and pwritev2

Message ID CAMe9rOqPfbjYPgEqmkWEAht+ZzGZk4wikhVCejUuMWtTdQjr8w@mail.gmail.com
State New, archived
Headers

Commit Message

H.J. Lu June 3, 2017, 11:27 a.m. UTC
  On Sat, Jun 3, 2017 at 4:23 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 06/03/2017 01:04 PM, H.J. Lu wrote:
>> On Sat, Jun 3, 2017 at 1:22 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>>> On Jun 02 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>
>>>> The x86-64 LO_HI_LONG can't be used for p{readv,writev}{64}v2.  Add a
>>>> new macro, LO_HI_LONG_FLAGS, to pass the off{64}_t and flags arguments.
>>>
>>> Why can't LO_HI_LONG just pass the padding unconditionally on x86_64?
>>>
>>
>> To avoid the unnecessary (long) (((uint64_t) (val)) >> 32).
>
> I think the question is why you can't define it like this:
>
>    (val), 0
>
> ?  Are you concerned about the additional overhead of passing that
> unnecessary zero at the end of the parameter list for other system
> calls?  Or would this result in an observable kernel interface
> difference and break stuff?

My patch has

ndex 7b8bd79..a3fe2fa 100644

For LO_HI_LONG, it doesn't mater what the second one is.  It makes
no difference if -1 is passed.  Why bother with 0?
  

Comments

H.J. Lu June 3, 2017, 11:29 a.m. UTC | #1
On Sat, Jun 3, 2017 at 4:27 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sat, Jun 3, 2017 at 4:23 AM, Florian Weimer <fweimer@redhat.com> wrote:
>> On 06/03/2017 01:04 PM, H.J. Lu wrote:
>>> On Sat, Jun 3, 2017 at 1:22 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>>>> On Jun 02 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>>
>>>>> The x86-64 LO_HI_LONG can't be used for p{readv,writev}{64}v2.  Add a
>>>>> new macro, LO_HI_LONG_FLAGS, to pass the off{64}_t and flags arguments.
>>>>
>>>> Why can't LO_HI_LONG just pass the padding unconditionally on x86_64?
>>>>
>>>
>>> To avoid the unnecessary (long) (((uint64_t) (val)) >> 32).
>>
>> I think the question is why you can't define it like this:
>>
>>    (val), 0
>>
>> ?  Are you concerned about the additional overhead of passing that
>> unnecessary zero at the end of the parameter list for other system
>> calls?  Or would this result in an observable kernel interface
>> difference and break stuff?
>
> My patch has
>
> ndex 7b8bd79..a3fe2fa 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
> +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
> @@ -389,4 +389,9 @@
>  #undef LO_HI_LONG
>  #define LO_HI_LONG(val) (val)
>
> +/* Provide a macro to pass the off{64}_t and flags arguments on
> +   p{readv,writev}{64}v2.  */
> +#undef LO_HI_LONG_FLAGS
> +#define LO_HI_LONG_FLAGS(val, flags) (val), 0, (flags)
> +
>  #endif /* linux/x86_64/sysdep.h */
>
> For LO_HI_LONG, it doesn't mater what the second one is.  It makes
> no difference if -1 is passed.  Why bother with 0?
>

BTW, LO_HI_LONG_FLAGS is still needed for x32 even if LO_HI_LONG
passes the second argument for x86-64.
  
Andreas Schwab June 3, 2017, 12:52 p.m. UTC | #2
On Jun 03 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:

> BTW, LO_HI_LONG_FLAGS is still needed for x32

Why?

Andreas.
  
H.J. Lu June 3, 2017, 12:57 p.m. UTC | #3
On Sat, Jun 3, 2017 at 5:52 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> On Jun 03 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>
>> BTW, LO_HI_LONG_FLAGS is still needed for x32
>
> Why?

For targets which define __ARCH_WANT_COMPAT_SYS_PREADV64V2 and
__ARCH_WANT_COMPAT_SYS_PWRITEV64V2,

(unsigned long fd, {const }struct iovec *iov, unsigned long vlen,
 unsigned long pos, int flags)

will be used for p{readv,writev}{64}v2.  X32 is the only such target.   The
64-bit pos and int flags are passed as 2 arguments to kernel here.  It is
incorrect to pass "pos, 0, flags" to kernel.
  
Zack Weinberg June 3, 2017, 1:48 p.m. UTC | #4
On 06/03/2017 07:27 AM, H.J. Lu wrote:
> On Sat, Jun 3, 2017 at 4:23 AM, Florian Weimer <fweimer@redhat.com> wrote:
>> On 06/03/2017 01:04 PM, H.J. Lu wrote:
>>> On Sat, Jun 3, 2017 at 1:22 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>>>> On Jun 02 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>>
>>>>> The x86-64 LO_HI_LONG can't be used for p{readv,writev}{64}v2.  Add a
>>>>> new macro, LO_HI_LONG_FLAGS, to pass the off{64}_t and flags arguments.
>>>>
>>>> Why can't LO_HI_LONG just pass the padding unconditionally on x86_64?
>>>>
>>>
>>> To avoid the unnecessary (long) (((uint64_t) (val)) >> 32).
>>
>> I think the question is why you can't define it like this:
>>
>>    (val), 0
>>
>> ?  Are you concerned about the additional overhead of passing that
>> unnecessary zero at the end of the parameter list for other system
>> calls?  Or would this result in an observable kernel interface
>> difference and break stuff?
> 
> My patch has
> 
> ndex 7b8bd79..a3fe2fa 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
> +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
> @@ -389,4 +389,9 @@
>  #undef LO_HI_LONG
>  #define LO_HI_LONG(val) (val)
> 
> +/* Provide a macro to pass the off{64}_t and flags arguments on
> +   p{readv,writev}{64}v2.  */
> +#undef LO_HI_LONG_FLAGS
> +#define LO_HI_LONG_FLAGS(val, flags) (val), 0, (flags)
> +
>  #endif /* linux/x86_64/sysdep.h */
> 
> For LO_HI_LONG, it doesn't mater what the second one is.  It makes
> no difference if -1 is passed.  Why bother with 0?

If nothing else, always passing the unused argument as 0 will reduce
confusion when people inspect these syscalls, e.g. through the debugger
interface or the seccomp filter interface.  I think that's a sufficient
reason to do it.  These are all I/O syscalls that can block, it's the
wrong place to be shaving cycles.

zw
  
H.J. Lu June 3, 2017, 1:52 p.m. UTC | #5
On Sat, Jun 3, 2017 at 6:48 AM, Zack Weinberg <zackw@panix.com> wrote:
> On 06/03/2017 07:27 AM, H.J. Lu wrote:
>> On Sat, Jun 3, 2017 at 4:23 AM, Florian Weimer <fweimer@redhat.com> wrote:
>>> On 06/03/2017 01:04 PM, H.J. Lu wrote:
>>>> On Sat, Jun 3, 2017 at 1:22 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>>>>> On Jun 02 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:
>>>>>
>>>>>> The x86-64 LO_HI_LONG can't be used for p{readv,writev}{64}v2.  Add a
>>>>>> new macro, LO_HI_LONG_FLAGS, to pass the off{64}_t and flags arguments.
>>>>>
>>>>> Why can't LO_HI_LONG just pass the padding unconditionally on x86_64?
>>>>>
>>>>
>>>> To avoid the unnecessary (long) (((uint64_t) (val)) >> 32).
>>>
>>> I think the question is why you can't define it like this:
>>>
>>>    (val), 0
>>>
>>> ?  Are you concerned about the additional overhead of passing that
>>> unnecessary zero at the end of the parameter list for other system
>>> calls?  Or would this result in an observable kernel interface
>>> difference and break stuff?
>>
>> My patch has
>>
>> ndex 7b8bd79..a3fe2fa 100644
>> --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
>> +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
>> @@ -389,4 +389,9 @@
>>  #undef LO_HI_LONG
>>  #define LO_HI_LONG(val) (val)
>>
>> +/* Provide a macro to pass the off{64}_t and flags arguments on
>> +   p{readv,writev}{64}v2.  */
>> +#undef LO_HI_LONG_FLAGS
>> +#define LO_HI_LONG_FLAGS(val, flags) (val), 0, (flags)
>> +
>>  #endif /* linux/x86_64/sysdep.h */
>>
>> For LO_HI_LONG, it doesn't mater what the second one is.  It makes
>> no difference if -1 is passed.  Why bother with 0?
>
> If nothing else, always passing the unused argument as 0 will reduce
> confusion when people inspect these syscalls, e.g. through the debugger
> interface or the seccomp filter interface.  I think that's a sufficient
> reason to do it.  These are all I/O syscalls that can block, it's the
> wrong place to be shaving cycles.

LO_HI_LONG_FLAGS is still needed for x32, regardless what we
do with LO_HI_LONG.
  
Zack Weinberg June 3, 2017, 1:58 p.m. UTC | #6
On 06/03/2017 09:52 AM, H.J. Lu wrote:
> On Sat, Jun 3, 2017 at 6:48 AM, Zack Weinberg <zackw@panix.com> wrote:
>> If nothing else, always passing the unused argument as 0 will reduce
>> confusion when people inspect these syscalls, e.g. through the debugger
>> interface or the seccomp filter interface.  I think that's a sufficient
>> reason to do it.  These are all I/O syscalls that can block, it's the
>> wrong place to be shaving cycles.
> 
> LO_HI_LONG_FLAGS is still needed for x32, regardless what we
> do with LO_HI_LONG.

But x32 won't get the definition of LO_HI_LONG that expands to "(val),
0)" - that would be wrong - so why won't LO_HI_LONG(val), flags work?

zw
  
H.J. Lu June 3, 2017, 2:16 p.m. UTC | #7
On Sat, Jun 3, 2017 at 6:58 AM, Zack Weinberg <zackw@panix.com> wrote:
> On 06/03/2017 09:52 AM, H.J. Lu wrote:
>> On Sat, Jun 3, 2017 at 6:48 AM, Zack Weinberg <zackw@panix.com> wrote:
>>> If nothing else, always passing the unused argument as 0 will reduce
>>> confusion when people inspect these syscalls, e.g. through the debugger
>>> interface or the seccomp filter interface.  I think that's a sufficient
>>> reason to do it.  These are all I/O syscalls that can block, it's the
>>> wrong place to be shaving cycles.
>>
>> LO_HI_LONG_FLAGS is still needed for x32, regardless what we
>> do with LO_HI_LONG.
>
> But x32 won't get the definition of LO_HI_LONG that expands to "(val),
> 0)" - that would be wrong - so why won't LO_HI_LONG(val), flags work?
>

X32 inherits LO_HI_LONG from x86-64.  If we change x86-64
LO_HI_LONG, x32 needs to redefine LO_HI_LONG.
  
Andreas Schwab June 3, 2017, 3:28 p.m. UTC | #8
On Jun 03 2017, "H.J. Lu" <hjl.tools@gmail.com> wrote:

> X32 inherits LO_HI_LONG from x86-64.  If we change x86-64
> LO_HI_LONG, x32 needs to redefine LO_HI_LONG.

Your LO_HI_LONG_FLAGS doesn't work for x32 either.

Andreas.
  

Patch

--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -389,4 +389,9 @@ 
 #undef LO_HI_LONG
 #define LO_HI_LONG(val) (val)

+/* Provide a macro to pass the off{64}_t and flags arguments on
+   p{readv,writev}{64}v2.  */
+#undef LO_HI_LONG_FLAGS
+#define LO_HI_LONG_FLAGS(val, flags) (val), 0, (flags)
+
 #endif /* linux/x86_64/sysdep.h */