summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
authorMichael Brown2008-06-11 14:16:02 +0200
committerMichael Brown2008-06-11 14:16:02 +0200
commitc3811d4a1339c29254db1ce04810259448840bcc (patch)
tree87b7cb9bca188469ba72074f70ee435c21774135 /src/net
parent[console] Call cpu_nap() only if there is no input waiting (diff)
downloadipxe-c3811d4a1339c29254db1ce04810259448840bcc.tar.gz
ipxe-c3811d4a1339c29254db1ce04810259448840bcc.tar.xz
ipxe-c3811d4a1339c29254db1ce04810259448840bcc.zip
[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.
Diffstat (limited to 'src/net')
-rw-r--r--src/net/udp/slam.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/src/net/udp/slam.c b/src/net/udp/slam.c
index 510b9b21..cb0dfa5c 100644
--- a/src/net/udp/slam.c
+++ b/src/net/udp/slam.c
@@ -94,12 +94,19 @@ FEATURE ( FEATURE_PROTOCOL, "SLAM", DHCP_EB_FEATURE_SLAM, 1 );
#define SLAM_MAX_HEADER_LEN ( 7 /* transaction id */ + 7 /* total_bytes */ + \
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
*
- * 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 */ + \
- 1 /* NUL */ )
+#define SLAM_MAX_NACK_LEN ( 7 /* block */ + 7 /* #blocks */ + 1 /* NUL */ )
/** SLAM slave timeout */
#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 ) {
struct io_buffer *iobuf;
- unsigned long block;
+ unsigned long first_block;
+ unsigned long num_blocks;
uint8_t *nul;
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
* RX checksumming, this would inevitably cause packet drops.
*/
- block = bitmap_first_gap ( &slam->bitmap );
- if ( block ) {
- DBGCP ( slam, "SLAM %p transmitting NACK for block %ld\n",
- slam, block );
+ first_block = bitmap_first_gap ( &slam->bitmap );
+ for ( num_blocks = 1 ; ; num_blocks++ ) {
+ if ( num_blocks >= SLAM_MAX_BLOCKS_PER_NACK )
+ break;
+ if ( ( first_block + num_blocks ) >= slam->num_blocks )
+ break;
+ if ( bitmap_test ( &slam->bitmap,
+ ( first_block + num_blocks ) ) )
+ break;
+ }
+ 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\n", slam );
+ DBGC ( slam, "SLAM %p transmitting initial NACK for blocks "
+ "0-%ld\n", slam, ( num_blocks - 1 ) );
}
- if ( ( rc = slam_put_value ( slam, iobuf, block ) ) != 0 )
+ if ( ( rc = slam_put_value ( slam, iobuf, first_block ) ) != 0 )
return rc;
- if ( ( rc = slam_put_value ( slam, iobuf, 1 ) ) != 0 )
+ if ( ( rc = slam_put_value ( slam, iobuf, num_blocks ) ) != 0 )
return rc;
nul = iob_put ( iobuf, 1 );
*nul = 0;