david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[slam] Add support for SLAM window lengths of greater than one packet

Add the definition of SLAM_MAX_BLOCKS_PER_NACK, which is roughly
equivalent to a TCP window size; it represents the maximum number of
packets that will be requested in a single NACK.

Note that, to keep the code size down, we still limit ourselves to
requesting only a single range per NACK; if the missing-block list is
discontiguous then we may request fewer than SLAM_MAX_BLOCKS_PER_NACK
blocks.
This commit is contained in:
Michael Brown 2008-06-11 13:16:02 +01:00
parent 50810955e9
commit c3811d4a13
1 changed files with 31 additions and 12 deletions

View File

@ -94,12 +94,19 @@ FEATURE ( FEATURE_PROTOCOL, "SLAM", DHCP_EB_FEATURE_SLAM, 1 );
#define SLAM_MAX_HEADER_LEN ( 7 /* transaction id */ + 7 /* total_bytes */ + \ #define SLAM_MAX_HEADER_LEN ( 7 /* transaction id */ + 7 /* total_bytes */ + \
7 /* block_size */ ) 7 /* block_size */ )
/** Maximum number of blocks to request per NACK
*
* This is a policy decision equivalent to selecting a TCP window
* size.
*/
#define SLAM_MAX_BLOCKS_PER_NACK 4
/** Maximum SLAM NACK length /** Maximum SLAM NACK length
* *
* We only ever send a NACK for a single packet. * We only ever send a NACK for a single range of up to @c
* SLAM_MAX_BLOCKS_PER_NACK blocks.
*/ */
#define SLAM_MAX_NACK_LEN ( 7 /* block */ + 1 /* #blocks = 1 */ + \ #define SLAM_MAX_NACK_LEN ( 7 /* block */ + 7 /* #blocks */ + 1 /* NUL */ )
1 /* NUL */ )
/** SLAM slave timeout */ /** SLAM slave timeout */
#define SLAM_SLAVE_TIMEOUT ( 1 * TICKS_PER_SEC ) #define SLAM_SLAVE_TIMEOUT ( 1 * TICKS_PER_SEC )
@ -242,7 +249,8 @@ static int slam_put_value ( struct slam_request *slam,
*/ */
static int slam_tx_nack ( struct slam_request *slam ) { static int slam_tx_nack ( struct slam_request *slam ) {
struct io_buffer *iobuf; struct io_buffer *iobuf;
unsigned long block; unsigned long first_block;
unsigned long num_blocks;
uint8_t *nul; uint8_t *nul;
int rc; int rc;
@ -263,16 +271,27 @@ static int slam_tx_nack ( struct slam_request *slam ) {
* data out as fast as it can. On a gigabit network, without * data out as fast as it can. On a gigabit network, without
* RX checksumming, this would inevitably cause packet drops. * RX checksumming, this would inevitably cause packet drops.
*/ */
block = bitmap_first_gap ( &slam->bitmap ); first_block = bitmap_first_gap ( &slam->bitmap );
if ( block ) { for ( num_blocks = 1 ; ; num_blocks++ ) {
DBGCP ( slam, "SLAM %p transmitting NACK for block %ld\n", if ( num_blocks >= SLAM_MAX_BLOCKS_PER_NACK )
slam, block ); break;
} else { if ( ( first_block + num_blocks ) >= slam->num_blocks )
DBGC ( slam, "SLAM %p transmitting initial NACK\n", slam ); break;
if ( bitmap_test ( &slam->bitmap,
( first_block + num_blocks ) ) )
break;
} }
if ( ( rc = slam_put_value ( slam, iobuf, block ) ) != 0 ) if ( first_block ) {
DBGCP ( slam, "SLAM %p transmitting NACK for blocks "
"%ld-%ld\n", slam, first_block,
( first_block + num_blocks - 1 ) );
} else {
DBGC ( slam, "SLAM %p transmitting initial NACK for blocks "
"0-%ld\n", slam, ( num_blocks - 1 ) );
}
if ( ( rc = slam_put_value ( slam, iobuf, first_block ) ) != 0 )
return rc; return rc;
if ( ( rc = slam_put_value ( slam, iobuf, 1 ) ) != 0 ) if ( ( rc = slam_put_value ( slam, iobuf, num_blocks ) ) != 0 )
return rc; return rc;
nul = iob_put ( iobuf, 1 ); nul = iob_put ( iobuf, 1 );
*nul = 0; *nul = 0;