summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
authorMichael Brown2008-06-10 12:23:34 +0200
committerMichael Brown2008-06-10 12:23:34 +0200
commit1e5c2d48cbb15bfad2ac1f777acec51f702df908 (patch)
tree6c80de5ef8b10443e6f0763389f25b2066590177 /src/net
parent[slam] Fix multicast address parsing (diff)
downloadipxe-1e5c2d48cbb15bfad2ac1f777acec51f702df908.tar.gz
ipxe-1e5c2d48cbb15bfad2ac1f777acec51f702df908.tar.xz
ipxe-1e5c2d48cbb15bfad2ac1f777acec51f702df908.zip
[slam] Speed up NACK transmission by restricting the block-list length
Shorter NACK packets take less time to construct and spew out less debug output, and there's a limit to how useful it is to send a complete missing-block list anyway; if the loss rate is high then we're going to have to retransmit an updated missing-block list anyway. Also add pretty debugging output to show the list of requested blocks.
Diffstat (limited to 'src/net')
-rw-r--r--src/net/udp/slam.c82
1 files changed, 62 insertions, 20 deletions
diff --git a/src/net/udp/slam.c b/src/net/udp/slam.c
index 160a5d97..e51c068f 100644
--- a/src/net/udp/slam.c
+++ b/src/net/udp/slam.c
@@ -93,6 +93,16 @@ FEATURE ( FEATURE_PROTOCOL, "SLAM", DHCP_EB_FEATURE_SLAM, 1 );
#define SLAM_MAX_HEADER_LEN ( 8 /* transaction id */ + 8 /* total_bytes */ + \
8 /* block_size */ )
+/** Maximum SLAM NACK length
+ *
+ * This is a policy decision. Shorter packets take less time to
+ * construct and spew out less debug output, and there's a limit to
+ * how useful it is to send a complete missing-block list anyway; if
+ * the loss rate is high then we're going to have to retransmit an
+ * updated missing-block list anyway.
+ */
+#define SLAM_MAX_NACK_LEN 16
+
/** A SLAM request */
struct slam_request {
/** Reference counter */
@@ -198,8 +208,8 @@ static int slam_put_value ( struct slam_request *slam,
*/
len = ( ( flsl ( value ) + 10 ) / 8 );
if ( len >= iob_tailroom ( iobuf ) ) {
- DBGC ( slam, "SLAM %p cannot add %d-byte value\n",
- slam, len );
+ DBGC2 ( slam, "SLAM %p cannot add %d-byte value\n",
+ slam, len );
return -ENOBUFS;
}
/* There is no valid way within the protocol that we can end
@@ -221,17 +231,59 @@ static int slam_put_value ( struct slam_request *slam,
}
/**
- * Send SLAM NACK packet
+ * Build SLAM compressed missing-block list
*
* @v slam SLAM request
+ * @v iobuf I/O buffer
* @ret rc Return status code
*/
-static int slam_tx_nack ( struct slam_request *slam ) {
- struct io_buffer *iobuf;
+static int slam_build_block_list ( struct slam_request *slam,
+ struct io_buffer *iobuf ) {
unsigned int block;
unsigned int block_count;
int block_present;
int last_block_present;
+ int rc;
+
+ DBGC ( slam, "SLAM %p asking for ", slam );
+
+ /* Walk bitmap to construct list */
+ block_count = 0;
+ last_block_present = ( ! 0 );
+ for ( block = 0 ; block < slam->num_blocks ; block++ ) {
+ block_present = ( !! bitmap_test ( &slam->bitmap, block ) );
+ if ( block_present != last_block_present ) {
+ if ( ( rc = slam_put_value ( slam, iobuf,
+ block_count ) ) != 0 ) {
+ DBGC ( slam, "...\n" );
+ return rc;
+ }
+ DBGC ( slam, "%c%d",
+ ( last_block_present ? ' ' : '-' ),
+ ( last_block_present ? block : block - 1 ) );
+ block_count = 0;
+ last_block_present = block_present;
+ }
+ block_count++;
+ }
+ if ( ( rc = slam_put_value ( slam, iobuf, block_count ) ) != 0 ) {
+ DBGC ( slam, "...\n" );
+ return rc;
+ }
+ DBGC ( slam, "%c%d\n", ( last_block_present ? ' ' : '-' ),
+ ( last_block_present ? block : block - 1 ) );
+
+ return 0;
+}
+
+/**
+ * Send SLAM NACK packet
+ *
+ * @v slam SLAM request
+ * @ret rc Return status code
+ */
+static int slam_tx_nack ( struct slam_request *slam ) {
+ struct io_buffer *iobuf;
uint8_t *nul;
DBGC ( slam, "SLAM %p transmitting NACK\n", slam );
@@ -243,26 +295,17 @@ static int slam_tx_nack ( struct slam_request *slam ) {
* data we can fit in a packet. If we overrun, it seems to be
* acceptable to drop information anyway.
*/
- iobuf = xfer_alloc_iob ( &slam->socket, slam->block_size );
+ iobuf = xfer_alloc_iob ( &slam->socket, SLAM_MAX_NACK_LEN );
if ( ! iobuf ) {
DBGC ( slam, "SLAM %p could not allocate I/O buffer\n",
slam );
return -ENOMEM;
}
- /* Walk bitmap to construct list */
- block_count = 0;
- last_block_present = ( ! 0 );
- for ( block = 0 ; block < slam->num_blocks ; block++ ) {
- block_present = ( !! bitmap_test ( &slam->bitmap, block ) );
- if ( block_present != last_block_present ) {
- slam_put_value ( slam, iobuf, block_count );
- block_count = 0;
- last_block_present = block_present;
- }
- block_count++;
- }
- slam_put_value ( slam, iobuf, block_count );
+ /* Build block list. (Errors are non-fatal; it just means we
+ * couldn't fit the compressed list within the packet.)
+ */
+ slam_build_block_list ( slam, iobuf );
/* Add NUL terminator */
nul = iob_put ( iobuf, 1 );
@@ -697,7 +740,6 @@ static int slam_open ( struct xfer_interface *xfer, struct uri *uri ) {
/* Fake an invalid cached header of { 0x00, ... } */
slam->header_len = 1;
/* Fake parameters for initial NACK */
- slam->block_size = 512;
slam->num_blocks = 1;
if ( ( rc = bitmap_resize ( &slam->bitmap, 1 ) ) != 0 ) {
DBGC ( slam, "SLAM %p could not allocate initial bitmap: "