Skip to content

Commit

Permalink
[peerdist] Gather and report peer statistics during download
Browse files Browse the repository at this point in the history
Record and report the number of peers (calculated as the maximum
number of peers discovered for a block's segment at the time that the
block download is complete), and the percentage of blocks retrieved
from peers rather than from the origin server.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Sep 5, 2017
1 parent 4674df2 commit 7e673a6
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/include/ipxe/peerdisc.h
Expand Up @@ -109,6 +109,12 @@ peerdisc_init ( struct peerdisc_client *peerdisc,

extern unsigned int peerdisc_timeout_secs;

extern void peerdisc_stat ( struct interface *intf, struct peerdisc_peer *peer,
struct list_head *peers );
#define peerdisc_stat_TYPE( object_type ) \
typeof ( void ( object_type, struct peerdisc_peer *peer, \
struct list_head *peers ) )

extern int peerdisc_open ( struct peerdisc_client *peerdisc, const void *id,
size_t len );
extern void peerdisc_close ( struct peerdisc_client *peerdisc );
Expand Down
13 changes: 13 additions & 0 deletions src/include/ipxe/peermux.h
Expand Up @@ -41,6 +41,16 @@ struct peerdist_multiplexed_block {
struct interface xfer;
};

/** PeerDist statistics */
struct peerdist_statistics {
/** Maximum observed number of peers */
unsigned int peers;
/** Number of blocks downloaded in total */
unsigned int total;
/** Number of blocks downloaded from peers */
unsigned int local;
};

/** A PeerDist download multiplexer */
struct peerdist_multiplexer {
/** Reference count */
Expand All @@ -65,6 +75,9 @@ struct peerdist_multiplexer {
struct list_head idle;
/** Block downloads */
struct peerdist_multiplexed_block block[PEERMUX_MAX_BLOCKS];

/** Statistics */
struct peerdist_statistics stats;
};

extern int peermux_filter ( struct interface *xfer, struct interface *info,
Expand Down
8 changes: 8 additions & 0 deletions src/net/peerblk.c
Expand Up @@ -270,6 +270,9 @@ static int peerblk_deliver ( struct peerdist_block *peerblk,
*/
static void peerblk_done ( struct peerdist_block *peerblk, int rc ) {
struct digest_algorithm *digest = peerblk->digest;
struct peerdisc_segment *segment = peerblk->discovery.segment;
struct peerdisc_peer *head;
struct peerdisc_peer *peer;
uint8_t hash[digest->digestsize];
unsigned long now = peerblk_timestamp();

Expand All @@ -296,6 +299,11 @@ static void peerblk_done ( struct peerdist_block *peerblk, int rc ) {
profile_custom ( &peerblk_attempt_success_profiler,
( now - peerblk->attempted ) );

/* Report peer statistics */
head = list_entry ( &segment->peers, struct peerdisc_peer, list );
peer = ( ( peerblk->peer == head ) ? NULL : peerblk->peer );
peerdisc_stat ( &peerblk->xfer, peer, &segment->peers );

/* Close download */
peerblk_close ( peerblk, 0 );
return;
Expand Down
30 changes: 30 additions & 0 deletions src/net/peerdisc.c
Expand Up @@ -76,6 +76,36 @@ static struct peerdisc_segment * peerdisc_find ( const char *id );
static int peerdisc_discovered ( struct peerdisc_segment *segment,
const char *location );

/******************************************************************************
*
* Statistics reporting
*
******************************************************************************
*/

/**
* Report peer discovery statistics
*
* @v intf Interface
* @v peer Selected peer (or NULL)
* @v peers List of available peers
*/
void peerdisc_stat ( struct interface *intf, struct peerdisc_peer *peer,
struct list_head *peers ) {
struct interface *dest;
peerdisc_stat_TYPE ( void * ) *op =
intf_get_dest_op ( intf, peerdisc_stat, &dest );
void *object = intf_object ( dest );

if ( op ) {
op ( object, peer, peers );
} else {
/* Default is to do nothing */
}

intf_put ( dest );
}

/******************************************************************************
*
* Discovery sockets
Expand Down
57 changes: 57 additions & 0 deletions src/net/peermux.c
Expand Up @@ -24,9 +24,11 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ipxe/uri.h>
#include <ipxe/xferbuf.h>
#include <ipxe/job.h>
#include <ipxe/peerblk.h>
#include <ipxe/peermux.h>

Expand Down Expand Up @@ -74,6 +76,28 @@ static void peermux_close ( struct peerdist_multiplexer *peermux, int rc ) {
intf_shutdown ( &peermux->info, rc );
}

/**
* Report progress of PeerDist download
*
* @v peermux PeerDist download multiplexer
* @v progress Progress report to fill in
* @ret ongoing_rc Ongoing job status code (if known)
*/
static int peermux_progress ( struct peerdist_multiplexer *peermux,
struct job_progress *progress ) {
struct peerdist_statistics *stats = &peermux->stats;
unsigned int percentage;

/* Construct PeerDist status message */
if ( stats->total ) {
percentage = ( ( 100 * stats->local ) / stats->total );
snprintf ( progress->message, sizeof ( progress->message ),
"%3d%% from %d peers", percentage, stats->peers );
}

return 0;
}

/**
* Receive content information
*
Expand Down Expand Up @@ -274,6 +298,35 @@ peermux_block_buffer ( struct peerdist_multiplexed_block *peermblk ) {
return xfer_buffer ( &peermux->xfer );
}

/**
* Record peer discovery statistics
*
* @v peermblk PeerDist multiplexed block download
* @v peer Selected peer (or NULL)
* @v peers List of available peers
*/
static void peermux_block_stat ( struct peerdist_multiplexed_block *peermblk,
struct peerdisc_peer *peer,
struct list_head *peers ) {
struct peerdist_multiplexer *peermux = peermblk->peermux;
struct peerdist_statistics *stats = &peermux->stats;
struct peerdisc_peer *tmp;
unsigned int count = 0;

/* Record maximum number of available peers */
list_for_each_entry ( tmp, peers, list )
count++;
if ( count > stats->peers )
stats->peers = count;

/* Update block counts */
if ( peer )
stats->local++;
stats->total++;
DBGC2 ( peermux, "PEERMUX %p downloaded %d/%d from %d peers\n",
peermux, stats->local, stats->total, stats->peers );
}

/**
* Close multiplexed block download
*
Expand Down Expand Up @@ -303,6 +356,8 @@ static void peermux_block_close ( struct peerdist_multiplexed_block *peermblk,

/** Data transfer interface operations */
static struct interface_operation peermux_xfer_operations[] = {
INTF_OP ( job_progress, struct peerdist_multiplexer *,
peermux_progress ),
INTF_OP ( intf_close, struct peerdist_multiplexer *, peermux_close ),
};

Expand Down Expand Up @@ -330,6 +385,8 @@ static struct interface_operation peermux_block_operations[] = {
peermux_block_deliver ),
INTF_OP ( xfer_buffer, struct peerdist_multiplexed_block *,
peermux_block_buffer ),
INTF_OP ( peerdisc_stat, struct peerdist_multiplexed_block *,
peermux_block_stat ),
INTF_OP ( intf_close, struct peerdist_multiplexed_block *,
peermux_block_close ),
};
Expand Down

0 comments on commit 7e673a6

Please sign in to comment.