diff mbox series

net: Shrink sock.sk_err sk_err_soft to u16 from int

Message ID 74c6f54cd3869258f4c83b46d9e5b95f7f0dab4b.1656878516.git.cdleonard@gmail.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net: Shrink sock.sk_err sk_err_soft to u16 from int | expand

Checks

Context Check Description
netdev/tree_selection success Guessed tree name to be net-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix warning Target tree name not specified in the subject
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 2865 this patch: 2865
netdev/cc_maintainers success CCed 5 of 5 maintainers
netdev/build_clang success Errors and warnings before: 631 this patch: 631
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 2990 this patch: 2990
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Leonard Crestez July 3, 2022, 8:06 p.m. UTC
These fields hold positive errno values which are limited by
ERRNO_MAX=4095 so 16 bits is more than enough.

They are also always positive; setting them to a negative errno value
can result in falsely reporting a successful read/write of incorrect
size.

Signed-off-by: Leonard Crestez <cdleonard@gmail.com>
---
 include/net/sock.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

I ran some relatively complex tests without noticing issues but some corner
case where this breaks might exist.

Comments

Paolo Abeni July 5, 2022, 10:31 a.m. UTC | #1
On Sun, 2022-07-03 at 23:06 +0300, Leonard Crestez wrote:
> These fields hold positive errno values which are limited by
> ERRNO_MAX=4095 so 16 bits is more than enough.
> 
> They are also always positive; setting them to a negative errno value
> can result in falsely reporting a successful read/write of incorrect
> size.
> 
> Signed-off-by: Leonard Crestez <cdleonard@gmail.com>
> ---
>  include/net/sock.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> I ran some relatively complex tests without noticing issues but some corner
> case where this breaks might exist.

Could you please explain in length the rationale behind this change?

Note that this additionally changes the struct sock binary layout,
which in turn in quite relevant for high speed data transfer.

Thanks!

Paolo
Leonard Crestez July 5, 2022, 1:01 p.m. UTC | #2
On 7/5/22 13:31, Paolo Abeni wrote:
> On Sun, 2022-07-03 at 23:06 +0300, Leonard Crestez wrote:
>> These fields hold positive errno values which are limited by
>> ERRNO_MAX=4095 so 16 bits is more than enough.
>>
>> They are also always positive; setting them to a negative errno value
>> can result in falsely reporting a successful read/write of incorrect
>> size.
>>
>> Signed-off-by: Leonard Crestez <cdleonard@gmail.com>
>> ---
>>   include/net/sock.h | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> I ran some relatively complex tests without noticing issues but some corner
>> case where this breaks might exist.
> 
> Could you please explain in length the rationale behind this change?
> 
> Note that this additionally changes the struct sock binary layout,
> which in turn in quite relevant for high speed data transfer.

The rationale is that shrinking structs is almost always better. I know 
that due to various roundings it likely won't actually impact memory 
consumption unless accumulated with other size reductions.

These sk_err fields don't seem to be in a particularly "hot" area so I 
don't think it will impact performance.

My expectation is that after a socket error is reported the socket will 
likely be closed so that there will be very few writes to this field.

--
Regards,
Leonard
Jakub Kicinski July 5, 2022, 7:06 p.m. UTC | #3
On Sun,  3 Jul 2022 23:06:43 +0300 Leonard Crestez wrote:
> -	int			sk_err,
> +	u16			sk_err,
>  				sk_err_soft;

While at it please remove the comma and explicitly type both fields.

BTW are there are no architectures of note which can't load 2B entities,
any more? Historically 16b is an awkward quantity for RISC arches.
Soheil Hassas Yeganeh July 5, 2022, 10:26 p.m. UTC | #4
On Tue, Jul 5, 2022 at 9:01 AM Leonard Crestez <cdleonard@gmail.com> wrote:
>
> On 7/5/22 13:31, Paolo Abeni wrote:
> > On Sun, 2022-07-03 at 23:06 +0300, Leonard Crestez wrote:
> >> These fields hold positive errno values which are limited by
> >> ERRNO_MAX=4095 so 16 bits is more than enough.
> >>
> >> They are also always positive; setting them to a negative errno value
> >> can result in falsely reporting a successful read/write of incorrect
> >> size.
> >>
> >> Signed-off-by: Leonard Crestez <cdleonard@gmail.com>
> >> ---
> >>   include/net/sock.h | 2 +-
> >>   1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> I ran some relatively complex tests without noticing issues but some corner
> >> case where this breaks might exist.
> >
> > Could you please explain in length the rationale behind this change?
> >
> > Note that this additionally changes the struct sock binary layout,
> > which in turn in quite relevant for high speed data transfer.
>
> The rationale is that shrinking structs is almost always better. I know
> that due to various roundings it likely won't actually impact memory
> consumption unless accumulated with other size reductions.
>
> These sk_err fields don't seem to be in a particularly "hot" area so I
> don't think it will impact performance.
>
> My expectation is that after a socket error is reported the socket will
> likely be closed so that there will be very few writes to this field.

Since you're packing sk_err and sk_err_soft into a DWORD, I'd suggest
adding another patch on top to move both fields right before sk_filter
where we have a 4-byte hole. As far as I can tell, this should save
one QWORD from "struct sock".

Eric, I believe these fields are read-mostly and that wouldn't infer
with your previous layout optimizations. Is my understanding correct?

Thanks,
Soheil

> --
> Regards,
> Leonard
Eric Dumazet July 6, 2022, 2:04 p.m. UTC | #5
On Sun, Jul 3, 2022 at 10:07 PM Leonard Crestez <cdleonard@gmail.com> wrote:
>
> These fields hold positive errno values which are limited by
> ERRNO_MAX=4095 so 16 bits is more than enough.
>
> They are also always positive; setting them to a negative errno value
> can result in falsely reporting a successful read/write of incorrect
> size.
>
> Signed-off-by: Leonard Crestez <cdleonard@gmail.com>
> ---

We can not do this safely.

sk->sk_err_soft can be written without lock, this needs to be a full integer,
otherwise this might pollute adjacent bytes.

>  include/net/sock.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> I ran some relatively complex tests without noticing issues but some corner
> case where this breaks might exist.
>
> diff --git a/include/net/sock.h b/include/net/sock.h
> index 0dd43c3df49b..acd85d1702d9 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -480,11 +480,11 @@ struct sock {
>         u16                     sk_protocol;
>         u16                     sk_gso_max_segs;
>         unsigned long           sk_lingertime;
>         struct proto            *sk_prot_creator;
>         rwlock_t                sk_callback_lock;
> -       int                     sk_err,
> +       u16                     sk_err,
>                                 sk_err_soft;
>         u32                     sk_ack_backlog;
>         u32                     sk_max_ack_backlog;
>         kuid_t                  sk_uid;
>         u8                      sk_txrehash;
> --
> 2.25.1
>
diff mbox series

Patch

diff --git a/include/net/sock.h b/include/net/sock.h
index 0dd43c3df49b..acd85d1702d9 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -480,11 +480,11 @@  struct sock {
 	u16			sk_protocol;
 	u16			sk_gso_max_segs;
 	unsigned long	        sk_lingertime;
 	struct proto		*sk_prot_creator;
 	rwlock_t		sk_callback_lock;
-	int			sk_err,
+	u16			sk_err,
 				sk_err_soft;
 	u32			sk_ack_backlog;
 	u32			sk_max_ack_backlog;
 	kuid_t			sk_uid;
 	u8			sk_txrehash;