aboutsummaryrefslogtreecommitdiff
path: root/src/net/peermux.c
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2019-08-12 22:58:21 +0100
committerMichael Brown <mcb30@ipxe.org>2019-08-12 23:05:58 +0100
commitc9e393e727debc150a7aa5806e0d740f53b1b8d5 (patch)
tree12547538508204e1de141cd85e615b20c6e77623 /src/net/peermux.c
parentc63ef427a2b18d318b313a4adf6267bb4dfa0c1c (diff)
downloadipxe-c9e393e727debc150a7aa5806e0d740f53b1b8d5.zip
ipxe-c9e393e727debc150a7aa5806e0d740f53b1b8d5.tar.gz
ipxe-c9e393e727debc150a7aa5806e0d740f53b1b8d5.tar.bz2
[peerdist] Reduce number of concurrent requests to origin serverpeerdist
Origin server requests are likely to be significantly more expensive than local peer requests: they consume sparse uplink bandwidth and, if using HTTPS, substantial local resources. Start with a low number of concurrent block downloads and adjust this number in response to the availability of local peers, in order to avoid hammering the origin server with the full concurrency limit. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/peermux.c')
-rw-r--r--src/net/peermux.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/net/peermux.c b/src/net/peermux.c
index a391ed3..c354f21 100644
--- a/src/net/peermux.c
+++ b/src/net/peermux.c
@@ -92,7 +92,8 @@ static int peermux_progress ( struct peerdist_multiplexer *peermux,
if ( stats->total ) {
percentage = ( ( 100 * stats->local ) / stats->total );
snprintf ( progress->message, sizeof ( progress->message ),
- "%3d%% from %d peers", percentage, stats->peers );
+ "%3d%% from %d peers (x%d)", percentage,
+ stats->peers, peermux->limit );
}
return 0;
@@ -184,14 +185,17 @@ static void peermux_step ( struct peerdist_multiplexer *peermux ) {
unsigned int next_block;
int rc;
- /* Stop initiation process if all block downloads are busy */
- peermblk = list_first_entry ( &peermux->idle,
- struct peerdist_multiplexed_block, list );
- if ( ! peermblk ) {
+ /* Stop initiation process if we have reached the concurrency limit */
+ if ( peermux->count >= peermux->limit ) {
process_del ( &peermux->process );
return;
}
+ /* Get next available idle block download */
+ peermblk = list_first_entry ( &peermux->idle,
+ struct peerdist_multiplexed_block, list );
+ assert ( peermblk != NULL );
+
/* Increment block index */
next_block = ( block->index + 1 );
@@ -251,6 +255,7 @@ static void peermux_step ( struct peerdist_multiplexer *peermux ) {
/* Move to list of busy block downloads */
list_del ( &peermblk->list );
list_add_tail ( &peermblk->list, &peermux->busy );
+ peermux->count++;
return;
@@ -319,12 +324,19 @@ static void peermux_block_stat ( struct peerdist_multiplexed_block *peermblk,
if ( count > stats->peers )
stats->peers = count;
- /* Update block counts */
- if ( peer )
+ /* Update block counts and concurrency limit */
+ if ( peer ) {
stats->local++;
+ if ( peermux->limit < PEERMUX_MAX_BLOCKS )
+ peermux->limit++;
+ } else {
+ if ( peermux->limit > PEERMUX_MIN_BLOCKS )
+ peermux->limit--;
+ }
stats->total++;
- DBGC2 ( peermux, "PEERMUX %p downloaded %d/%d from %d peers\n",
- peermux, stats->local, stats->total, stats->peers );
+ DBGC2 ( peermux, "PEERMUX %p downloaded %d/%d from %d peers (x%d)\n",
+ peermux, stats->local, stats->total, stats->peers,
+ peermux->limit );
}
/**
@@ -340,6 +352,7 @@ static void peermux_block_close ( struct peerdist_multiplexed_block *peermblk,
/* Move to list of idle downloads */
list_del ( &peermblk->list );
list_add_tail ( &peermblk->list, &peermux->idle );
+ peermux->count--;
/* If any error occurred, terminate the whole multiplexer */
if ( rc != 0 ) {
@@ -426,6 +439,7 @@ int peermux_filter ( struct interface *xfer, struct interface *info,
&peermux->cache.info.raw.data );
process_init_stopped ( &peermux->process, &peermux_process_desc,
&peermux->refcnt );
+ peermux->limit = PEERMUX_MIN_BLOCKS;
INIT_LIST_HEAD ( &peermux->busy );
INIT_LIST_HEAD ( &peermux->idle );
for ( i = 0 ; i < PEERMUX_MAX_BLOCKS ; i++ ) {