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>
Change-Id: I5fda6798068d171868fd3d52873778c993f20a9f
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _UAPI_ASM_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* __ASM_AVR32_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _ASM_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _ASM_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _ASM_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _ASM_IA64_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _ASM_M32R_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _UAPI_ASM_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _ASM_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 0x4026
-#endif /* _UAPI_ASM_SOCKET_H */
+#define SO_MAX_PACING_RATE 0x4027
+
+#endif /* _ASM_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _ASM_POWERPC_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _ASM_SOCKET_H */
#define SO_SELECT_ERR_QUEUE 0x0029
+#define SO_MAX_PACING_RATE 0x0030
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* _XTENSA_SOCKET_H */
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;
#define SO_SELECT_ERR_QUEUE 45
+#define SO_MAX_PACING_RATE 46
+
#endif /* __ASM_GENERIC_SOCKET_H */
sock_valbool_flag(sk, SOCK_SELECT_ERR_QUEUE, 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;
v.val = sock_flag(sk, SOCK_SELECT_ERR_QUEUE);
break;
+ case SO_MAX_PACING_RATE:
+ v.val = sk->sk_max_pacing_rate;
+ break;
+
default:
return -ENOPROTOOPT;
}
sk->sk_stamp = ktime_set(-1L, 0);
sk->sk_pacing_rate = ~0U;
+
+ sk->sk_max_pacing_rate = ~0U;
/*
* Before updating sk_refcnt, we must commit prior changes to memory
* (Documentation/RCU/rculist_nulls.txt for details)
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