Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
David Goulet
Tor
Commits
61fc9c41
Commit
61fc9c41
authored
Sep 12, 2017
by
Matt Traudt
Committed by
David Goulet
Sep 15, 2017
Browse files
sched: switch to monotonic time; add/fix comments, style, and logs msgs
parent
6e598bbc
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/or/scheduler.c
View file @
61fc9c41
...
...
@@ -289,8 +289,8 @@ set_scheduler(void)
if
(
old_scheduler
&&
old_scheduler
->
free_all
)
{
old_scheduler
->
free_all
();
}
/* We don't clean up the old
one, w
e keep any type of scheduler
we've
* allocated so we can do an easy switch back. */
/* We don't clean up the old
scheduler_t. W
e keep any type of scheduler
*
we've
allocated so we can do an easy switch back. */
/* Initialize the new scheduler. */
if
(
scheduler
->
init
)
{
...
...
src/or/scheduler.h
View file @
61fc9c41
...
...
@@ -62,10 +62,10 @@ typedef struct scheduler_s {
/* (Optional) To be called whenever Tor finds out about a new consensus.
* First the scheduling system as a whole will react to the new consensus
* and change the scheduler if needed. After that,
whatever is the (possibly
*
new) scheduler
will call this so it has the chance to react to the
new
* consensus too. If there's a consensus parameter that your scheduler
wants
* to keep an eye on, this is where you should check for it. */
* and change the scheduler if needed. After that,
the current scheduler
*
(which might be new)
will call this so it has the chance to react to the
*
new
consensus too. If there's a consensus parameter that your scheduler
*
wants
to keep an eye on, this is where you should check for it. */
void
(
*
on_new_consensus
)(
const
networkstatus_t
*
old_c
,
const
networkstatus_t
*
new_c
);
...
...
src/or/scheduler_kist.c
View file @
61fc9c41
...
...
@@ -86,9 +86,16 @@ HT_GENERATE2(outbuf_table_s, outbuf_table_ent_s, node, outbuf_table_ent_hash,
* Other internal data
*****************************************************************************/
static
struct
timeval
scheduler_last_run
=
{
0
,
0
};
/* Store the last time the scheduler was run so we can decide when to next run
* the scheduler based on it. */
static
monotime_t
scheduler_last_run
;
/* This is a factor for the extra_space calculation in kist per-socket limits.
* It is the number of extra congestion windows we want to write to the kernel.
*/
static
double
sock_buf_size_factor
=
1
.
0
;
/* How often the scheduler runs. */
STATIC
int32_t
sched_run_interval
=
10
;
/* Stores the kist scheduler function pointers. */
static
scheduler_t
*
kist_scheduler
=
NULL
;
/*****************************************************************************
...
...
@@ -170,6 +177,8 @@ free_socket_info_by_chan(socket_table_t *table, const channel_t *chan)
free_socket_info_by_ent
(
ent
,
NULL
);
}
/* Perform system calls for the given socket in order to calculate kist's
* per-socket limit as documented in the function body. */
MOCK_IMPL
(
void
,
update_socket_info_impl
,
(
socket_table_ent_t
*
ent
))
{
...
...
@@ -191,8 +200,9 @@ update_socket_info_impl, (socket_table_ent_t *ent))
* 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."
);
"for KIST anymore. We will fallback to the naive "
"approach. Set KISTSchedRunInterval=-1 to disable "
"KIST."
);
kist_no_kernel_support
=
1
;
}
goto
fallback
;
...
...
@@ -200,8 +210,9 @@ update_socket_info_impl, (socket_table_ent_t *ent))
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."
);
"for KIST anymore. We will fallback to the naive "
"approach. Set KISTSchedRunInterval=-1 to disable "
"KIST."
);
/* Same reason as the above. */
kist_no_kernel_support
=
1
;
}
...
...
@@ -211,10 +222,19 @@ update_socket_info_impl, (socket_table_ent_t *ent))
ent
->
unacked
=
tcp
.
tcpi_unacked
;
ent
->
mss
=
tcp
.
tcpi_snd_mss
;
/* TCP space is the number of bytes would could give to the kernel and it
* would be able to immediately push them to the network. */
tcp_space
=
(
ent
->
cwnd
-
ent
->
unacked
)
*
ent
->
mss
;
if
(
tcp_space
<
0
)
{
tcp_space
=
0
;
}
/* Imagine we have filled up tcp_space already for a socket and the scheduler
* isn't going to run again for a while. We should write a little extra to the
* kernel so it has some data to send between scheduling runs if it gets ACKs
* back so it doesn't sit idle. With the suggested sock_buf_size_factor of
* 1.0, a socket can have at most 2*cwnd data in the kernel: 1 cwnd on the
* wire waiting for ACKs and 1 cwnd ready and waiting to be sent when those
* ACKs come. */
extra_space
=
clamp_double_to_int64
((
ent
->
cwnd
*
ent
->
mss
)
*
sock_buf_size_factor
)
-
ent
->
notsent
;
...
...
@@ -225,6 +245,12 @@ update_socket_info_impl, (socket_table_ent_t *ent))
return
;
fallback:
/* If all of a sudden we don't have kist support, we just zero out all the
* variables for this socket since we don't know what they should be.
* We also effectively allow the socket write as much as it wants to the
* kernel, effectively returning it to vanilla scheduler behavior. Writes
* are still limited by the lower layers of Tor: socket blocking, full
* outbuf, etc. */
ent
->
cwnd
=
ent
->
unacked
=
ent
->
mss
=
ent
->
notsent
=
0
;
ent
->
limit
=
INT_MAX
;
}
...
...
@@ -391,7 +417,7 @@ kist_scheduler_on_new_consensus(const networkstatus_t *old_c,
set_scheduler_run_interval
(
new_c
);
}
/* Function of the scheduler interface:
run
() */
/* Function of the scheduler interface:
on_new_options
() */
static
void
kist_scheduler_on_new_options
(
void
)
{
...
...
@@ -413,15 +439,16 @@ kist_scheduler_init(void)
static
void
kist_scheduler_schedule
(
void
)
{
struct
timeval
now
,
next_run
;
struct
monotime_t
now
;
struct
timeval
next_run
;
int32_t
diff
;
struct
event
*
ev
=
get_run_sched_ev
();
tor_assert
(
ev
);
if
(
!
have_work
())
{
return
;
}
tor_gettimeofday
(
&
now
);
diff
=
(
int32_t
)
tv_mdiff
(
&
scheduler_last_run
,
&
now
);
monotime_get
(
&
now
);
diff
=
(
int32_t
)
monotime_diff_msec
(
&
scheduler_last_run
,
&
now
);
if
(
diff
<
sched_run_interval
)
{
next_run
.
tv_sec
=
0
;
/* 1000 for ms -> us */
...
...
@@ -465,7 +492,9 @@ kist_scheduler_run(void)
/* if we have switched to a new channel, consider writing the previous
* channel's outbuf to the kernel. */
if
(
!
prev_chan
)
prev_chan
=
chan
;
if
(
!
prev_chan
)
{
prev_chan
=
chan
;
}
if
(
prev_chan
!=
chan
)
{
if
(
channel_should_write_to_kernel
(
&
outbuf_table
,
prev_chan
))
{
channel_write_to_kernel
(
prev_chan
);
...
...
@@ -522,9 +551,17 @@ kist_scheduler_run(void)
/* Case 3: cells to send, but cannot write */
/*
* We want to write, but can't. If we left the channel in
* channels_pending, we would never exit the scheduling loop. We need to
* add it to a temporary list of channels to be added to channels_pending
* after the scheduling loop is over. They can hopefully be taken care of
* in the next scheduling round.
*/
chan
->
scheduler_state
=
SCHED_CHAN_WAITING_TO_WRITE
;
if
(
!
to_readd
)
if
(
!
to_readd
)
{
to_readd
=
smartlist_new
();
}
smartlist_add
(
to_readd
,
chan
);
log_debug
(
LD_SCHED
,
"chan=%"
PRIu64
" now waiting_to_write"
,
chan
->
global_identifier
);
...
...
@@ -560,7 +597,7 @@ kist_scheduler_run(void)
smartlist_free
(
to_readd
);
}
tor_gettimeofday
(
&
scheduler_last_run
);
monotime_get
(
&
scheduler_last_run
);
}
/*****************************************************************************
...
...
@@ -593,7 +630,7 @@ get_kist_scheduler(void)
/* Maximum interval that KIST runs (in ms). */
#define KIST_SCHED_RUN_INTERVAL_MAX 100
/* Check the torrc for the configured KIST scheduler run
frequency
.
/* Check the torrc for the configured KIST scheduler run
interval
.
* - If torrc < 0, then return the negative torrc value (shouldn't even be
* using KIST)
* - If torrc > 0, then return the positive torrc value (should use KIST, and
...
...
src/or/scheduler_vanilla.c
View file @
61fc9c41
...
...
@@ -17,6 +17,7 @@
/* Maximum cells to flush in a single call to channel_flush_some_cells(); */
#define MAX_FLUSH_CELLS 1000
/* Stores the vanilla scheduler function pointers. */
static
scheduler_t
*
vanilla_scheduler
=
NULL
;
/*****************************************************************************
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment