net: allow tcp tuning via /proc/sys/mars/tcp_tuning/

This commit is contained in:
Thomas Schoebel-Theuer 2013-11-22 11:38:11 +01:00
parent 7ad628a725
commit 62d9dd371a
3 changed files with 58 additions and 43 deletions

View File

@ -37,23 +37,28 @@ module_param_named(mars_port, mars_net_default_port, int, 0);
*/ */
struct mars_tcp_params default_tcp_params = { struct mars_tcp_params default_tcp_params = {
.window_size = 8 * 1024 * 1024, // for long distance replications .ip_tos = IPTOS_LOWDELAY,
.tcp_window_size = 8 * 1024 * 1024, // for long distance replications
.tcp_nodelay = 0,
.tcp_timeout = 20, .tcp_timeout = 20,
.tcp_keepcnt = 3, .tcp_keepcnt = 3,
.tcp_keepintvl = 10, // keepalive ping time .tcp_keepintvl = 10, // keepalive ping time
.tcp_keepidle = 10, .tcp_keepidle = 10,
.tos = IPTOS_LOWDELAY,
}; };
EXPORT_SYMBOL(default_tcp_params); EXPORT_SYMBOL(default_tcp_params);
static static
void _check(int status) void __setsockopt(struct socket *sock, int level, int optname, char *optval, int optsize)
{ {
int status = kernel_setsockopt(sock, level, optname, optval, optsize);
if (status < 0) { if (status < 0) {
MARS_WRN("cannot set socket option, status = %d\n", status); MARS_WRN("cannot set %d socket option %d to value %d, status = %d\n",
level, optname, *(int*)optval, status);
} }
} }
#define _setsockopt(sock,level,optname,val) __setsockopt(sock, level, optname, (char*)&(val), sizeof(val))
int mars_create_sockaddr(struct sockaddr_storage *addr, const char *spec) int mars_create_sockaddr(struct sockaddr_storage *addr, const char *spec)
{ {
struct sockaddr_in *sockaddr = (void*)addr; struct sockaddr_in *sockaddr = (void*)addr;
@ -117,47 +122,28 @@ static int current_debug_nr = 0; // no locking, just for debugging
static static
void _set_socketopts(struct socket *sock) void _set_socketopts(struct socket *sock)
{ {
struct timeval t = {
.tv_sec = default_tcp_params.tcp_timeout,
};
int x_true = 1; int x_true = 1;
int status;
/* TODO: improve this by a table-driven approach /* TODO: improve this by a table-driven approach
*/ */
sock->sk->sk_rcvtimeo = sock->sk->sk_sndtimeo = default_tcp_params.tcp_timeout * HZ; sock->sk->sk_rcvtimeo = sock->sk->sk_sndtimeo = default_tcp_params.tcp_timeout * HZ;
sock->sk->sk_reuse = 1; sock->sk->sk_reuse = 1;
status = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&default_tcp_params.window_size, sizeof(default_tcp_params.window_size)); _setsockopt(sock, SOL_SOCKET, SO_SNDBUFFORCE, default_tcp_params.tcp_window_size);
_check(status); _setsockopt(sock, SOL_SOCKET, SO_RCVBUFFORCE, default_tcp_params.tcp_window_size);
status = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&default_tcp_params.window_size, sizeof(default_tcp_params.window_size)); _setsockopt(sock, SOL_IP, SO_PRIORITY, default_tcp_params.ip_tos);
_check(status); _setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, default_tcp_params.tcp_nodelay);
status = kernel_setsockopt(sock, SOL_IP, SO_PRIORITY, (char*)&default_tcp_params.tos, sizeof(default_tcp_params.tos)); _setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, x_true);
_check(status); _setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, default_tcp_params.tcp_keepcnt);
#if 0 _setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, default_tcp_params.tcp_keepintvl);
status = kernel_setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&x_true, sizeof(x_true)); _setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, default_tcp_params.tcp_keepidle);
#endif _setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, t);
_check(status); _setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, t);
status = kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&x_true, sizeof(x_true));
_check(status);
status = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (char*)&default_tcp_params.tcp_keepcnt, sizeof(default_tcp_params.tcp_keepcnt));
_check(status);
status = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (char*)&default_tcp_params.tcp_keepintvl, sizeof(default_tcp_params.tcp_keepintvl));
_check(status);
status = kernel_setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (char*)&default_tcp_params.tcp_keepidle, sizeof(default_tcp_params.tcp_keepidle));
_check(status);
#if 1
{
struct timeval t = {
.tv_sec = default_tcp_params.tcp_timeout,
};
status = kernel_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&t, sizeof(t));
status = kernel_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&t, sizeof(t));
_check(status);
}
#endif
#if 1
if (sock->file) { // switch back to blocking mode if (sock->file) { // switch back to blocking mode
sock->file->f_flags &= ~O_NONBLOCK; sock->file->f_flags &= ~O_NONBLOCK;
} }
#endif
} }
int mars_create_socket(struct mars_socket *msock, struct sockaddr_storage *addr, bool is_server) int mars_create_socket(struct mars_socket *msock, struct sockaddr_storage *addr, bool is_server)

View File

@ -50,12 +50,13 @@ struct mars_socket {
}; };
struct mars_tcp_params { struct mars_tcp_params {
int ip_tos;
int tcp_window_size;
int tcp_nodelay;
int tcp_timeout; int tcp_timeout;
int window_size;
int tcp_keepcnt; int tcp_keepcnt;
int tcp_keepintvl; int tcp_keepintvl;
int tcp_keepidle; int tcp_keepidle;
char tos;
}; };
extern struct mars_tcp_params default_tcp_params; extern struct mars_tcp_params default_tcp_params;

View File

@ -201,9 +201,13 @@ EXPORT_SYMBOL_GPL(mars_max_loadavg);
INT_ENTRY(PREFIX "_true_hit", (VAR)->thr_true_hit, 0400) \ INT_ENTRY(PREFIX "_true_hit", (VAR)->thr_true_hit, 0400) \
static static
ctl_table tuning_table[] = { ctl_table traffic_tuning_table[] = {
LIMITER_ENTRIES(&client_limiter, "traffic", "kb"), LIMITER_ENTRIES(&client_limiter, "client_role_traffic", "kb"),
LIMITER_ENTRIES(&server_limiter, "server_io", "kb"), LIMITER_ENTRIES(&server_limiter, "server_role_traffic", "kb"),
};
static
ctl_table io_tuning_table[] = {
LIMITER_ENTRIES(&global_writeback.limiter, "writeback", "kb"), LIMITER_ENTRIES(&global_writeback.limiter, "writeback", "kb"),
INT_ENTRY("writeback_until_percent", global_writeback.until_percent, 0600), INT_ENTRY("writeback_until_percent", global_writeback.until_percent, 0600),
THRESHOLD_ENTRIES(&bio_submit_threshold, "bio_submit"), THRESHOLD_ENTRIES(&bio_submit_threshold, "bio_submit"),
@ -216,6 +220,18 @@ ctl_table tuning_table[] = {
{} {}
}; };
static
ctl_table tcp_tuning_table[] = {
INT_ENTRY("ip_tos", default_tcp_params.ip_tos, 0600),
INT_ENTRY("tcp_window_size", default_tcp_params.tcp_window_size, 0600),
INT_ENTRY("tcp_nodelay", default_tcp_params.tcp_nodelay, 0600),
INT_ENTRY("tcp_timeout", default_tcp_params.tcp_timeout, 0600),
INT_ENTRY("tcp_keepcnt", default_tcp_params.tcp_keepcnt, 0600),
INT_ENTRY("tcp_keepintvl", default_tcp_params.tcp_keepintvl, 0600),
INT_ENTRY("tcp_keepidle", default_tcp_params.tcp_keepidle, 0600),
{}
};
static static
ctl_table mars_table[] = { ctl_table mars_table[] = {
{ {
@ -300,9 +316,21 @@ ctl_table mars_table[] = {
INT_ENTRY("network_io_timeout", global_net_io_timeout, 0600), INT_ENTRY("network_io_timeout", global_net_io_timeout, 0600),
{ {
_CTL_NAME _CTL_NAME
.procname = "tuning", .procname = "traffic_tuning",
.mode = 0500, .mode = 0500,
.child = tuning_table, .child = traffic_tuning_table,
},
{
_CTL_NAME
.procname = "io_tuning",
.mode = 0500,
.child = io_tuning_table,
},
{
_CTL_NAME
.procname = "tcp_tuning",
.mode = 0500,
.child = tcp_tuning_table,
}, },
{} {}
}; };