aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2013-09-24 11:20:52 -0400
committerDavid S. Miller <davem@davemloft.net>2013-09-28 18:35:41 -0400
commit62748f32d501f5d3712a7c372bbb92abc7c62bc7 (patch)
tree847a6e4b66aaf012809ff8656476743e738f1a2b
parent4aa0a03f519812f48ac48d046bc451e97649ec82 (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.h4
-rw-r--r--arch/avr32/include/uapi/asm/socket.h2
-rw-r--r--arch/cris/include/uapi/asm/socket.h2
-rw-r--r--arch/frv/include/uapi/asm/socket.h2
-rw-r--r--arch/h8300/include/uapi/asm/socket.h2
-rw-r--r--arch/ia64/include/uapi/asm/socket.h2
-rw-r--r--arch/m32r/include/uapi/asm/socket.h2
-rw-r--r--arch/mips/include/uapi/asm/socket.h2
-rw-r--r--arch/mn10300/include/uapi/asm/socket.h2
-rw-r--r--arch/parisc/include/uapi/asm/socket.h2
-rw-r--r--arch/powerpc/include/uapi/asm/socket.h2
-rw-r--r--arch/s390/include/uapi/asm/socket.h2
-rw-r--r--arch/sparc/include/uapi/asm/socket.h2
-rw-r--r--arch/xtensa/include/uapi/asm/socket.h2
-rw-r--r--include/net/sock.h1
-rw-r--r--include/uapi/asm-generic/socket.h2
-rw-r--r--net/core/sock.c12
-rw-r--r--net/ipv4/tcp_input.c2
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