diff options
Diffstat (limited to 'src/or/scheduler_kist.c')
-rw-r--r-- | src/or/scheduler_kist.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/or/scheduler_kist.c b/src/or/scheduler_kist.c index 98b523f5ae..eff8ee1cb9 100644 --- a/src/or/scheduler_kist.c +++ b/src/or/scheduler_kist.c @@ -24,6 +24,11 @@ * Data structures and supporting functions *****************************************************************************/ +/* Indicate if we don't have the kernel support. This can happen if the kernel + * changed and it doesn't recognized the values passed to the syscalls needed + * by KIST. In that case, fallback to the naive approach. */ +static unsigned int kist_no_kernel_support = 0; + /* Socket_table hash table stuff. The socket_table keeps track of per-socket * limit information imposed by kist and used by kist. */ @@ -174,9 +179,34 @@ update_socket_info_impl, (socket_table_ent_t *ent)) struct tcp_info tcp; socklen_t tcp_info_len = sizeof(tcp); + if (kist_no_kernel_support) { + goto fallback; + } + /* Gather information */ - getsockopt(sock, SOL_TCP, TCP_INFO, (void *)&(tcp), &tcp_info_len); - ioctl(sock, SIOCOUTQNSD, &(ent->notsent)); + if (getsockopt(sock, SOL_TCP, TCP_INFO, (void *)&(tcp), &tcp_info_len) < 0) { + if (errno == EINVAL) { + /* Oops, this option is not provided by the kernel, we'll have to + * disable KIST entirely. This can happen if tor was built on a machine + * with the support previously or if the kernel was updated and lost the + * support. */ + log_notice(LD_SCHED, "Looks like our kernel doesn't have the support " + "for KIST anymore. Fallback to the naive approach. " + "Set KISTSchedRunInterval=-1 to disable KIST."); + kist_no_kernel_support = 1; + } + goto fallback; + } + if (ioctl(sock, SIOCOUTQNSD, &(ent->notsent)) < 0) { + if (errno == EINVAL) { + log_notice(LD_SCHED, "Looks like our kernel doesn't have the support " + "for KIST anymore. Fallback to the naive approach. " + "Set KISTSchedRunInterval=-1 to disable KIST."); + /* Same reason as the above. */ + kist_no_kernel_support = 1; + } + goto fallback; + } ent->cwnd = tcp.tcpi_snd_cwnd; ent->unacked = tcp.tcpi_unacked; ent->mss = tcp.tcpi_snd_mss; @@ -193,6 +223,10 @@ update_socket_info_impl, (socket_table_ent_t *ent)) } ent->limit = tcp_space + extra_space; return; + + fallback: + ent->cwnd = ent->unacked = ent->mss = ent->notsent = 0; + ent->limit = INT_MAX; } /* Given a socket that isn't in the table, add it. |