Throttle switching kernel acceleration
Creating/destroying interfaces etc. does take some time. When e.g. receiving a lot of sessions as new slave, we don't want to stay stuck creating hundreds of interfaces while we are already receiving control messages that we have to forward to master not too late. Switching kernel acceleration can wait a bit most of the time.
This commit is contained in:
parent
a22295d804
commit
a957ff08ee
2 changed files with 52 additions and 10 deletions
59
l2tpns.c
59
l2tpns.c
|
|
@ -137,6 +137,8 @@ static char time_now_string[64] = {0}; // Current time as a string.
|
|||
static int time_changed = 0; // time_now changed
|
||||
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
|
||||
linked_list *loaded_plugins;
|
||||
linked_list *plugins[MAX_PLUGIN_TYPES];
|
||||
|
||||
|
|
@ -1280,7 +1282,8 @@ 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
|
||||
static void set_kernel_accel(sessionidt s, int set)
|
||||
// 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)
|
||||
{
|
||||
if (set && !can_kernel_accel(s))
|
||||
/* Still cannot enable it */
|
||||
|
|
@ -1291,6 +1294,16 @@ static void set_kernel_accel(sessionidt s, int set)
|
|||
/* We don't know the tunnel yet */
|
||||
return;
|
||||
|
||||
if (set && !now && kernel_switches >= MAX_KERNEL_SWITCHES)
|
||||
{
|
||||
// We already performed many switches, throttle a bit by just
|
||||
// marking as pending
|
||||
sess_local[s].needs_switch = 1;
|
||||
return;
|
||||
}
|
||||
kernel_switches++;
|
||||
sess_local[s].needs_switch = 0;
|
||||
|
||||
routesset(s, &session[s], 0);
|
||||
if (session[s].ppp.ipv6cp == Opened)
|
||||
routes6set(s, &session[s], 0);
|
||||
|
|
@ -1323,7 +1336,7 @@ void switch_kernel_accel(sessionidt s)
|
|||
return;
|
||||
|
||||
/* Try to enable */
|
||||
set_kernel_accel(s, 1);
|
||||
set_kernel_accel(s, 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1334,7 +1347,7 @@ void switch_kernel_accel(sessionidt s)
|
|||
return;
|
||||
|
||||
/* Has to disable it */
|
||||
set_kernel_accel(s, 0);
|
||||
set_kernel_accel(s, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5805,7 +5818,7 @@ static void mainloop(void)
|
|||
sessionidt sid;
|
||||
for (sid = 1; sid <= config->cluster_highest_sessionid ; ++sid)
|
||||
if (session[sid].tunnel == tid)
|
||||
set_kernel_accel(sid, 0);
|
||||
set_kernel_accel(sid, 0, 1);
|
||||
|
||||
delete_kernel_tunnel(tid);
|
||||
}
|
||||
|
|
@ -5833,12 +5846,12 @@ static void mainloop(void)
|
|||
if (s < 0)
|
||||
{
|
||||
LOG(1, sid, tid, "Error on pppox socket: %s\n", strerror(errno));
|
||||
set_kernel_accel(sid, 0);
|
||||
set_kernel_accel(sid, 0, 1);
|
||||
}
|
||||
else if (s == 0)
|
||||
{
|
||||
LOG(1, sid, tid, "EOF on pppox socket\n");
|
||||
set_kernel_accel(sid, 0);
|
||||
set_kernel_accel(sid, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -5857,12 +5870,12 @@ static void mainloop(void)
|
|||
if (s < 0)
|
||||
{
|
||||
LOG(1, sid, tid, "Error on ppp channel: %s\n", strerror(errno));
|
||||
set_kernel_accel(sid, 0);
|
||||
set_kernel_accel(sid, 0, 1);
|
||||
}
|
||||
else if (s == 0)
|
||||
{
|
||||
LOG(1, sid, tid, "EOF on ppp channel\n");
|
||||
set_kernel_accel(sid, 0);
|
||||
set_kernel_accel(sid, 0, 1);
|
||||
}
|
||||
else
|
||||
processppp_from_kernel(sid, p, s, NULL);
|
||||
|
|
@ -5878,12 +5891,12 @@ static void mainloop(void)
|
|||
if (s < 0)
|
||||
{
|
||||
LOG(1, sid, tid, "Error on ppp if: %s\n", strerror(errno));
|
||||
set_kernel_accel(sid, 0);
|
||||
set_kernel_accel(sid, 0, 1);
|
||||
}
|
||||
else if (s == 0)
|
||||
{
|
||||
LOG(1, sid, tid, "EOF on ppp if\n");
|
||||
set_kernel_accel(sid, 0);
|
||||
set_kernel_accel(sid, 0, 1);
|
||||
}
|
||||
else
|
||||
processppp_from_kernel(sid, p, s, NULL);
|
||||
|
|
@ -6051,6 +6064,32 @@ static void mainloop(void)
|
|||
next_cluster_ping = TIME + config->cluster_hb_interval;
|
||||
}
|
||||
|
||||
// Handle trying to enable kernel accel
|
||||
{
|
||||
static double last_switch = 0;
|
||||
double this_switch;
|
||||
double diff;
|
||||
|
||||
TIME = now(&this_switch);
|
||||
diff = this_switch - last_switch;
|
||||
|
||||
// Run during idle time (after we've handled
|
||||
// all incoming packets) or every 1/10th sec
|
||||
if (!more || diff > 0.1)
|
||||
{
|
||||
kernel_switches = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
last_switch = this_switch;
|
||||
}
|
||||
}
|
||||
|
||||
if (!config->cluster_iam_master)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue