diff options
author | Eric Dumazet <edumazet@google.com> | 2013-09-24 11:20:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-09-28 18:35:41 -0400 |
commit | 62748f32d501f5d3712a7c372bbb92abc7c62bc7 (patch) | |
tree | 847a6e4b66aaf012809ff8656476743e738f1a2b | |
parent | 4aa0a03f519812f48ac48d046bc451e97649ec82 (diff) |
net: introduce SO_MAX_PACING_RATE
As mentioned in commit afe4fd062416b ("pkt_sched: fq: Fair Queue packet
scheduler"), this patch adds a new socket option.
SO_MAX_PACING_RATE offers the application the ability to cap the
rate computed by transport layer. Value is in bytes per second.
u32 val = 1000000;
setsockopt(sockfd, SOL_SOCKET, SO_MAX_PACING_RATE, &val, sizeof(val));
To be effectively paced, a flow must use FQ packet scheduler.
Note that a packet scheduler takes into account the headers for its
computations. The effective payload rate depends on MSS and retransmits
if any.
I chose to make this pacing rate a SOL_SOCKET option instead of a
TCP one because this can be used by other protocols.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Steinar H. Gunderson <sesse@google.com>
Cc: Michael Kerrisk <mtk.manpages@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/alpha/include/uapi/asm/socket.h | 4 | ||||
-rw-r--r-- | arch/avr32/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/cris/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/frv/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/h8300/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/ia64/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/m32r/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/mips/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/mn10300/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/parisc/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/s390/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/sparc/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | arch/xtensa/include/uapi/asm/socket.h | 2 | ||||
-rw-r--r-- | include/net/sock.h | 1 | ||||
-rw-r--r-- | include/uapi/asm-generic/socket.h | 2 | ||||
-rw-r--r-- | net/core/sock.c | 12 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 2 |
18 files changed, 45 insertions, 2 deletions
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index 467de010ea7e..e3a1491d5073 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h | |||
@@ -81,6 +81,8 @@ | |||
81 | 81 | ||
82 | #define SO_SELECT_ERR_QUEUE 45 | 82 | #define SO_SELECT_ERR_QUEUE 45 |
83 | 83 | ||
84 | #define SO_BUSY_POLL 46 | 84 | #define SO_BUSY_POLL 46 |
85 | |||
86 | #define SO_MAX_PACING_RATE 47 | ||
85 | 87 | ||
86 | #endif /* _UAPI_ASM_SOCKET_H */ | 88 | #endif /* _UAPI_ASM_SOCKET_H */ |
diff --git a/arch/avr32/include/uapi/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h index 11c4259c62fb..439936421434 100644 --- a/arch/avr32/include/uapi/asm/socket.h +++ b/arch/avr32/include/uapi/asm/socket.h | |||
@@ -76,4 +76,6 @@ | |||
76 | 76 | ||
77 | #define SO_BUSY_POLL 46 | 77 | #define SO_BUSY_POLL 46 |
78 | 78 | ||
79 | #define SO_MAX_PACING_RATE 47 | ||
80 | |||
79 | #endif /* __ASM_AVR32_SOCKET_H */ | 81 | #endif /* __ASM_AVR32_SOCKET_H */ |
diff --git a/arch/cris/include/uapi/asm/socket.h b/arch/cris/include/uapi/asm/socket.h index eb723e51554e..13829aaaeec5 100644 --- a/arch/cris/include/uapi/asm/socket.h +++ b/arch/cris/include/uapi/asm/socket.h | |||
@@ -78,6 +78,8 @@ | |||
78 | 78 | ||
79 | #define SO_BUSY_POLL 46 | 79 | #define SO_BUSY_POLL 46 |
80 | 80 | ||
81 | #define SO_MAX_PACING_RATE 47 | ||
82 | |||
81 | #endif /* _ASM_SOCKET_H */ | 83 | #endif /* _ASM_SOCKET_H */ |
82 | 84 | ||
83 | 85 | ||
diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h index f0cb1c341163..5d4299762426 100644 --- a/arch/frv/include/uapi/asm/socket.h +++ b/arch/frv/include/uapi/asm/socket.h | |||
@@ -76,5 +76,7 @@ | |||
76 | 76 | ||
77 | #define SO_BUSY_POLL 46 | 77 | #define SO_BUSY_POLL 46 |
78 | 78 | ||
79 | #define SO_MAX_PACING_RATE 47 | ||
80 | |||
79 | #endif /* _ASM_SOCKET_H */ | 81 | #endif /* _ASM_SOCKET_H */ |
80 | 82 | ||
diff --git a/arch/h8300/include/uapi/asm/socket.h b/arch/h8300/include/uapi/asm/socket.h index 9490758c5e2b..214ccaf3554a 100644 --- a/arch/h8300/include/uapi/asm/socket.h +++ b/arch/h8300/include/uapi/asm/socket.h | |||
@@ -76,4 +76,6 @@ | |||
76 | 76 | ||
77 | #define SO_BUSY_POLL 46 | 77 | #define SO_BUSY_POLL 46 |
78 | 78 | ||
79 | #define SO_MAX_PACING_RATE 47 | ||
80 | |||
79 | #endif /* _ASM_SOCKET_H */ | 81 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index 556d0701a155..c25302fb48d9 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h | |||
@@ -85,4 +85,6 @@ | |||
85 | 85 | ||
86 | #define SO_BUSY_POLL 46 | 86 | #define SO_BUSY_POLL 46 |
87 | 87 | ||
88 | #define SO_MAX_PACING_RATE 47 | ||
89 | |||
88 | #endif /* _ASM_IA64_SOCKET_H */ | 90 | #endif /* _ASM_IA64_SOCKET_H */ |
diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h index 24be7c8da86a..52966650114f 100644 --- a/arch/m32r/include/uapi/asm/socket.h +++ b/arch/m32r/include/uapi/asm/socket.h | |||
@@ -76,4 +76,6 @@ | |||
76 | 76 | ||
77 | #define SO_BUSY_POLL 46 | 77 | #define SO_BUSY_POLL 46 |
78 | 78 | ||
79 | #define SO_MAX_PACING_RATE 47 | ||
80 | |||
79 | #endif /* _ASM_M32R_SOCKET_H */ | 81 | #endif /* _ASM_M32R_SOCKET_H */ |
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 61c01f054d1b..0df9787cd84d 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h | |||
@@ -94,4 +94,6 @@ | |||
94 | 94 | ||
95 | #define SO_BUSY_POLL 46 | 95 | #define SO_BUSY_POLL 46 |
96 | 96 | ||
97 | #define SO_MAX_PACING_RATE 47 | ||
98 | |||
97 | #endif /* _UAPI_ASM_SOCKET_H */ | 99 | #endif /* _UAPI_ASM_SOCKET_H */ |
diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h index e2a2b203eb00..71dedcae55a6 100644 --- a/arch/mn10300/include/uapi/asm/socket.h +++ b/arch/mn10300/include/uapi/asm/socket.h | |||
@@ -76,4 +76,6 @@ | |||
76 | 76 | ||
77 | #define SO_BUSY_POLL 46 | 77 | #define SO_BUSY_POLL 46 |
78 | 78 | ||
79 | #define SO_MAX_PACING_RATE 47 | ||
80 | |||
79 | #endif /* _ASM_SOCKET_H */ | 81 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index 71700e636a8e..7c614d01f1fa 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h | |||
@@ -75,6 +75,8 @@ | |||
75 | 75 | ||
76 | #define SO_BUSY_POLL 0x4027 | 76 | #define SO_BUSY_POLL 0x4027 |
77 | 77 | ||
78 | #define SO_MAX_PACING_RATE 0x4048 | ||
79 | |||
78 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we | 80 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we |
79 | * have to define SOCK_NONBLOCK to a different value here. | 81 | * have to define SOCK_NONBLOCK to a different value here. |
80 | */ | 82 | */ |
diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h index a6d74467c9ed..fa698324a1fd 100644 --- a/arch/powerpc/include/uapi/asm/socket.h +++ b/arch/powerpc/include/uapi/asm/socket.h | |||
@@ -83,4 +83,6 @@ | |||
83 | 83 | ||
84 | #define SO_BUSY_POLL 46 | 84 | #define SO_BUSY_POLL 46 |
85 | 85 | ||
86 | #define SO_MAX_PACING_RATE 47 | ||
87 | |||
86 | #endif /* _ASM_POWERPC_SOCKET_H */ | 88 | #endif /* _ASM_POWERPC_SOCKET_H */ |
diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index 92494494692e..c286c2e868f0 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h | |||
@@ -82,4 +82,6 @@ | |||
82 | 82 | ||
83 | #define SO_BUSY_POLL 46 | 83 | #define SO_BUSY_POLL 46 |
84 | 84 | ||
85 | #define SO_MAX_PACING_RATE 47 | ||
86 | |||
85 | #endif /* _ASM_SOCKET_H */ | 87 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 4e1d66c3ce71..0f21e9a5ca18 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h | |||
@@ -72,6 +72,8 @@ | |||
72 | 72 | ||
73 | #define SO_BUSY_POLL 0x0030 | 73 | #define SO_BUSY_POLL 0x0030 |
74 | 74 | ||
75 | #define SO_MAX_PACING_RATE 0x0031 | ||
76 | |||
75 | /* Security levels - as per NRL IPv6 - don't actually do anything */ | 77 | /* Security levels - as per NRL IPv6 - don't actually do anything */ |
76 | #define SO_SECURITY_AUTHENTICATION 0x5001 | 78 | #define SO_SECURITY_AUTHENTICATION 0x5001 |
77 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 | 79 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 |
diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index c114483010c1..7db5c22faa68 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h | |||
@@ -87,4 +87,6 @@ | |||
87 | 87 | ||
88 | #define SO_BUSY_POLL 46 | 88 | #define SO_BUSY_POLL 46 |
89 | 89 | ||
90 | #define SO_MAX_PACING_RATE 47 | ||
91 | |||
90 | #endif /* _XTENSA_SOCKET_H */ | 92 | #endif /* _XTENSA_SOCKET_H */ |
diff --git a/include/net/sock.h b/include/net/sock.h index 4625d2eff461..240aa3f08cd6 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -363,6 +363,7 @@ struct sock { | |||
363 | int sk_wmem_queued; | 363 | int sk_wmem_queued; |
364 | gfp_t sk_allocation; | 364 | gfp_t sk_allocation; |
365 | u32 sk_pacing_rate; /* bytes per second */ | 365 | u32 sk_pacing_rate; /* bytes per second */ |
366 | u32 sk_max_pacing_rate; | ||
366 | netdev_features_t sk_route_caps; | 367 | netdev_features_t sk_route_caps; |
367 | netdev_features_t sk_route_nocaps; | 368 | netdev_features_t sk_route_nocaps; |
368 | int sk_gso_type; | 369 | int sk_gso_type; |
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index f04b69b6abf2..38f14d0264c3 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h | |||
@@ -78,4 +78,6 @@ | |||
78 | 78 | ||
79 | #define SO_BUSY_POLL 46 | 79 | #define SO_BUSY_POLL 46 |
80 | 80 | ||
81 | #define SO_MAX_PACING_RATE 47 | ||
82 | |||
81 | #endif /* __ASM_GENERIC_SOCKET_H */ | 83 | #endif /* __ASM_GENERIC_SOCKET_H */ |
diff --git a/net/core/sock.c b/net/core/sock.c index 5b6beba494a3..2bd9b3faa0d0 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -914,6 +914,13 @@ set_rcvbuf: | |||
914 | } | 914 | } |
915 | break; | 915 | break; |
916 | #endif | 916 | #endif |
917 | |||
918 | case SO_MAX_PACING_RATE: | ||
919 | sk->sk_max_pacing_rate = val; | ||
920 | sk->sk_pacing_rate = min(sk->sk_pacing_rate, | ||
921 | sk->sk_max_pacing_rate); | ||
922 | break; | ||
923 | |||
917 | default: | 924 | default: |
918 | ret = -ENOPROTOOPT; | 925 | ret = -ENOPROTOOPT; |
919 | break; | 926 | break; |
@@ -1177,6 +1184,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
1177 | break; | 1184 | break; |
1178 | #endif | 1185 | #endif |
1179 | 1186 | ||
1187 | case SO_MAX_PACING_RATE: | ||
1188 | v.val = sk->sk_max_pacing_rate; | ||
1189 | break; | ||
1190 | |||
1180 | default: | 1191 | default: |
1181 | return -ENOPROTOOPT; | 1192 | return -ENOPROTOOPT; |
1182 | } | 1193 | } |
@@ -2319,6 +2330,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
2319 | sk->sk_ll_usec = sysctl_net_busy_read; | 2330 | sk->sk_ll_usec = sysctl_net_busy_read; |
2320 | #endif | 2331 | #endif |
2321 | 2332 | ||
2333 | sk->sk_max_pacing_rate = ~0U; | ||
2322 | /* | 2334 | /* |
2323 | * Before updating sk_refcnt, we must commit prior changes to memory | 2335 | * Before updating sk_refcnt, we must commit prior changes to memory |
2324 | * (Documentation/RCU/rculist_nulls.txt for details) | 2336 | * (Documentation/RCU/rculist_nulls.txt for details) |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 5d083855c111..66aa816ad30b 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -735,7 +735,7 @@ static void tcp_update_pacing_rate(struct sock *sk) | |||
735 | if (tp->srtt > 8 + 2) | 735 | if (tp->srtt > 8 + 2) |
736 | do_div(rate, tp->srtt); | 736 | do_div(rate, tp->srtt); |
737 | 737 | ||
738 | sk->sk_pacing_rate = min_t(u64, rate, ~0U); | 738 | sk->sk_pacing_rate = min_t(u64, rate, sk->sk_max_pacing_rate); |
739 | } | 739 | } |
740 | 740 | ||
741 | /* Calculate rto without backoff. This is the second half of Van Jacobson's | 741 | /* Calculate rto without backoff. This is the second half of Van Jacobson's |