kernel accel: if switching takes a long time, back off
That can happen even with not many sessions, e.g. on a loaded machine with a lot of routes
This commit is contained in:
parent
b2942b3c53
commit
a56de89a4c
1 changed files with 19 additions and 7 deletions
26
l2tpns.c
26
l2tpns.c
|
|
@ -140,6 +140,7 @@ char main_quit = 0; // True if we're in the process of exiting.
|
|||
static char main_reload = 0; // Re-load pending
|
||||
#define MAX_KERNEL_SWITCHES 20 // Maximum number of kernel switches per 1/10th second
|
||||
static int kernel_switches = 0; // How many kernel switches we performed since last cleanup
|
||||
static double last_poll_time = 0; // Last time we polled fds
|
||||
linked_list *loaded_plugins;
|
||||
linked_list *plugins[MAX_PLUGIN_TYPES];
|
||||
|
||||
|
|
@ -1387,7 +1388,7 @@ static int delete_kernel_accel(sessionidt s)
|
|||
// Enable (set=1) or disable (set=0) kernel PPP acceleration
|
||||
// This basically calls create/delete_kernel_accel, but also updates routes
|
||||
// If now is 0, we may delay this if we have already made a lot of switches since last cleanup
|
||||
static void set_kernel_accel(sessionidt s, int set, int now)
|
||||
static void set_kernel_accel(sessionidt s, int set, int nodelay)
|
||||
{
|
||||
if (set && !can_kernel_accel(s))
|
||||
/* Still cannot enable it */
|
||||
|
|
@ -1418,10 +1419,14 @@ static void set_kernel_accel(sessionidt s, int set, int now)
|
|||
}
|
||||
}
|
||||
|
||||
if (set && !now && kernel_switches >= MAX_KERNEL_SWITCHES)
|
||||
double cur_switch;
|
||||
now(&cur_switch);
|
||||
if (set && !nodelay &&
|
||||
(kernel_switches >= MAX_KERNEL_SWITCHES
|
||||
|| cur_switch - last_poll_time > 0.02))
|
||||
{
|
||||
// We already performed many switches, throttle a bit by just
|
||||
// marking as pending
|
||||
// We have already been switching a lot or working at for 20ms since last poll,
|
||||
// throttle a bit by just marking as pending
|
||||
sess_local[s].needs_switch = 1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -5999,7 +6004,7 @@ static void mainloop(void)
|
|||
n = epoll_wait(epollfd, events, maxevent, 100); // timeout 100ms (1/10th sec)
|
||||
STAT(select_called);
|
||||
|
||||
TIME = now(NULL);
|
||||
TIME = now(&last_poll_time);
|
||||
if (n < 0)
|
||||
{
|
||||
if (errno == EINTR ||
|
||||
|
|
@ -6387,7 +6392,7 @@ static void mainloop(void)
|
|||
// Handle trying to enable kernel accel
|
||||
{
|
||||
static double last_switch = 0;
|
||||
double this_switch;
|
||||
double this_switch, cur_switch;
|
||||
double diff;
|
||||
|
||||
TIME = now(&this_switch);
|
||||
|
|
@ -6399,14 +6404,21 @@ static void mainloop(void)
|
|||
{
|
||||
kernel_switches = 0;
|
||||
|
||||
cur_switch = this_switch;
|
||||
for (i = 1; i <= config->cluster_highest_sessionid; i++)
|
||||
{
|
||||
// Delayed kernel switch
|
||||
if (session[i].ppp.lcp == Opened && sess_local[i].needs_switch)
|
||||
{
|
||||
set_kernel_accel(i, can_kernel_accel(i), 0);
|
||||
TIME = now(&cur_switch);
|
||||
if (cur_switch - this_switch > 0.02)
|
||||
// We have already taken 20ms sec doing switches, backoff
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
last_switch = this_switch;
|
||||
last_switch = cur_switch;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue