mirror of
https://gitlab.com/qemu-project/ipxe.git
synced 2025-11-03 07:59:06 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9e393e727 |
@ -18,6 +18,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/xferbuf.h>
|
||||
#include <ipxe/pccrc.h>
|
||||
|
||||
/** Minimum number of concurrent block downloads */
|
||||
#define PEERMUX_MIN_BLOCKS 2
|
||||
|
||||
/** Maximum number of concurrent block downloads */
|
||||
#define PEERMUX_MAX_BLOCKS 32
|
||||
|
||||
@ -69,6 +72,10 @@ struct peerdist_multiplexer {
|
||||
|
||||
/** Block download initiation process */
|
||||
struct process process;
|
||||
/** Number of concurrent block downloads */
|
||||
unsigned int count;
|
||||
/** Maximum number of concurrent block downloads */
|
||||
unsigned int limit;
|
||||
/** List of busy block downloads */
|
||||
struct list_head busy;
|
||||
/** List of idle block downloads */
|
||||
|
||||
@ -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++ ) {
|
||||
|
||||
Reference in New Issue
Block a user