net: introduce SO_MAX_PACING_RATE

As mentioned in commit afe4fd0624 ("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>
Change-Id: Iea51b6104a5420d5c9ed1ea7382cbd53bdb8f4be
This commit is contained in:
Eric Dumazet 2013-09-24 08:20:52 -07:00 committed by surblazer
parent e5a9f4f1cc
commit adc3caedd0
20 changed files with 47 additions and 1 deletions

View File

@ -76,6 +76,8 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#ifdef __KERNEL__
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here.

View File

@ -69,4 +69,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_SOCKET_H */

View File

@ -69,4 +69,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* __ASM_AVR32_SOCKET_H */

View File

@ -71,6 +71,8 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_SOCKET_H */

View File

@ -69,5 +69,7 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_SOCKET_H */

View File

@ -69,4 +69,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_SOCKET_H */

View File

@ -78,4 +78,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_IA64_SOCKET_H */

View File

@ -69,4 +69,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_M32R_SOCKET_H */

View File

@ -69,4 +69,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_SOCKET_H */

View File

@ -89,6 +89,8 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#ifdef __KERNEL__
/** sock_type - Socket types

View File

@ -69,4 +69,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_SOCKET_H */

View File

@ -68,6 +68,7 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 0x4024
#define SO_MAX_PACING_RATE 0x4025
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here.

View File

@ -76,4 +76,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_POWERPC_SOCKET_H */

View File

@ -77,4 +77,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* _ASM_SOCKET_H */

View File

@ -65,6 +65,7 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 0x0027
#define SO_MAX_PACING_RATE 0x0028
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001

View File

@ -80,4 +80,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 47
#endif /* _XTENSA_SOCKET_H */

View File

@ -72,4 +72,6 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#define SO_MAX_PACING_RATE 44
#endif /* __ASM_GENERIC_SOCKET_H */

View File

@ -335,6 +335,7 @@ struct sock {
int sk_wmem_queued;
gfp_t sk_allocation;
u32 sk_pacing_rate; /* bytes per second */
u32 sk_max_pacing_rate;
netdev_features_t sk_route_caps;
netdev_features_t sk_route_nocaps;
int sk_gso_type;

View File

@ -792,6 +792,12 @@ set_rcvbuf:
sock_valbool_flag(sk, SOCK_NOFCS, valbool);
break;
case SO_MAX_PACING_RATE:
sk->sk_max_pacing_rate = val;
sk->sk_pacing_rate = min(sk->sk_pacing_rate,
sk->sk_max_pacing_rate);
break;
default:
ret = -ENOPROTOOPT;
break;
@ -1032,6 +1038,11 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
case SO_NOFCS:
v.val = !!sock_flag(sk, SOCK_NOFCS);
break;
case SO_MAX_PACING_RATE:
v.val = sk->sk_max_pacing_rate;
break;
default:
return -ENOPROTOOPT;
}
@ -2109,6 +2120,8 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_stamp = ktime_set(-1L, 0);
sk->sk_max_pacing_rate = ~0U;
/*
* Before updating sk_refcnt, we must commit prior changes to memory
* (Documentation/RCU/rculist_nulls.txt for details)

View File

@ -725,7 +725,7 @@ static void tcp_update_pacing_rate(struct sock *sk)
if (tp->srtt > 8 + 2)
do_div(rate, tp->srtt);
sk->sk_pacing_rate = min_t(u64, rate, ~0U);
sk->sk_pacing_rate = min_t(u64, rate, sk->sk_max_pacing_rate);
}
/* Calculate rto without backoff. This is the second half of Van Jacobson's