Skip to content

tas: Implement TCP Window Scale option #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/packet_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,19 @@ struct tcp_hdr {
#define TCP_OPT_END_OF_OPTIONS 0
#define TCP_OPT_NO_OP 1
#define TCP_OPT_MSS 2
#define TCP_OPT_WS 3
#define TCP_OPT_TIMESTAMP 8
struct tcp_mss_opt {
uint8_t kind;
uint8_t length;
beui16_t mss;
} __attribute__((packed));

struct tcp_ws_opt {
uint8_t kind;
uint8_t length;
uint8_t scale;
} __attribute__((packed));

struct tcp_timestamp_opt {
uint8_t kind;
Expand Down
15 changes: 10 additions & 5 deletions include/tas_memif.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,17 @@ struct flextcp_pl_flowst {
/** Sequence number of queue pointer bumps */
uint16_t bump_seq;

// 56
/** TX Window scale factor */
uint8_t tx_window_scale;
/** RX Window scale factor */
uint8_t rx_window_scale;
// 58

/********************************************************/
/* read-write fields */

/** spin lock */
volatile uint32_t lock;
/** Duplicate ack count */
uint16_t rx_dupack_cnt;

/** Bytes available for received segments at next position */
uint32_t rx_avail;
Expand All @@ -279,8 +283,9 @@ struct flextcp_pl_flowst {
uint32_t rx_next_seq;
/** Bytes available in remote end for received segments */
uint32_t rx_remote_avail;
/** Duplicate ack count */
uint32_t rx_dupack_cnt;

/** spin lock */
volatile uint32_t lock;

#ifdef FLEXNIC_PL_OOO_RECV
/* Start of interval of out-of-order received data */
Expand Down
15 changes: 14 additions & 1 deletion tas/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ enum cfg_params {
CP_TCP_TXBUF_LEN,
CP_TCP_HANDSHAKE_TO,
CP_TCP_HANDSHAKE_RETRIES,
CP_TCP_WINDOW_SCALE,
CP_CC,
CP_CC_CONTROL_GRANULARITY,
CP_CC_CONTROL_INTERVAL,
Expand Down Expand Up @@ -123,6 +124,9 @@ static struct option opts[] = {
{ .name = "tcp-handshake-retries",
.has_arg = required_argument,
.val = CP_TCP_HANDSHAKE_RETRIES },
{ .name = "tcp-window-scale",
.has_arg = required_argument,
.val = CP_TCP_WINDOW_SCALE },
{ .name = "cc",
.has_arg = required_argument,
.val = CP_CC },
Expand Down Expand Up @@ -327,6 +331,12 @@ int config_parse(struct configuration *c, int argc, char *argv[])
goto failed;
}
break;
case CP_TCP_WINDOW_SCALE:
if (parse_int8(optarg, &c->tcp_window_scale) != 0) {
fprintf(stderr, "tcp window scale parsing failed\n");
goto failed;
}
break;
case CP_CC:
if (!strcmp(optarg, "dctcp-win")) {
c->cc_algorithm = CONFIG_CC_DCTCP_WIN;
Expand Down Expand Up @@ -565,6 +575,7 @@ static int config_defaults(struct configuration *c, char *progname)
c->tcp_txbuf_len = 8192;
c->tcp_handshake_to = 10000;
c->tcp_handshake_retries = 10;
c->tcp_window_scale = 0;
c->cc_algorithm = CONFIG_CC_DCTCP_RATE;
c->cc_control_granularity = 50;
c->cc_control_interval = 2;
Expand Down Expand Up @@ -635,6 +646,8 @@ static void print_usage(struct configuration *c, char *progname)
"[default: %"PRIu32"]\n"
" --tcp-handshake-retries=RETRIES Handshake retries "
"[default: %"PRIu32"]\n"
" --tcp-window-scale=SCALE Window scale factor "
"[default: %"PRIu8"]\n"
"\n"
"Congestion control parameters:\n"
" --cc=ALGORITHM Congestion-control algorithm "
Expand Down Expand Up @@ -711,7 +724,7 @@ static void print_usage(struct configuration *c, char *progname)
progname, c->shm_len,
c->nic_rx_len, c->nic_tx_len, c->app_kin_len, c->app_kout_len,
c->tcp_rtt_init, c->tcp_link_bw, c->tcp_rxbuf_len, c->tcp_txbuf_len,
c->tcp_handshake_to, c->tcp_handshake_retries,
c->tcp_handshake_to, c->tcp_handshake_retries, c->tcp_window_scale,
c->cc_control_granularity, c->cc_control_interval, c->cc_rexmit_ints,
(double) c->cc_dctcp_weight / UINT32_MAX, c->cc_dctcp_min,
c->cc_const_rate, c->cc_timely_tlow, c->cc_timely_thigh,
Expand Down
22 changes: 12 additions & 10 deletions tas/fast/fast_flows.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@ static void flow_rx_seq_write(struct flextcp_pl_flowst *fs, uint32_t seq,
static void flow_tx_segment(struct dataplane_context *ctx,
struct network_buf_handle *nbh, struct flextcp_pl_flowst *fs,
uint32_t seq, uint32_t ack, uint32_t rxwnd, uint16_t payload,
uint32_t payload_pos, uint32_t ts_echo, uint32_t ts_my, uint8_t fin);
uint32_t payload_pos, uint32_t ts_echo, uint32_t ts_my,
uint8_t window_scale, uint8_t fin);
static void flow_tx_ack(struct dataplane_context *ctx, uint32_t seq,
uint32_t ack, uint32_t rxwnd, uint32_t echo_ts, uint32_t my_ts,
struct network_buf_handle *nbh, struct tcp_timestamp_opt *ts_opt);
uint8_t window_scale, struct network_buf_handle *nbh, struct tcp_timestamp_opt *ts_opt);
static void flow_reset_retransmit(struct flextcp_pl_flowst *fs);

static inline void tcp_checksums(struct network_buf_handle *nbh,
Expand Down Expand Up @@ -195,7 +196,7 @@ int fast_flows_qman(struct dataplane_context *ctx, uint32_t queue,

/* send out segment */
flow_tx_segment(ctx, nbh, fs, tx_seq, ack, rx_wnd, len, tx_pos,
fs->tx_next_ts, ts, fin);
fs->tx_next_ts, ts, fs->rx_window_scale, fin);
unlock:
fs_unlock(fs);
return ret;
Expand Down Expand Up @@ -499,7 +500,7 @@ int fast_flows_packet(struct dataplane_context *ctx,
}
}

fs->rx_remote_avail = f_beui16(p->tcp.wnd);
fs->rx_remote_avail = f_beui16(p->tcp.wnd) << fs->tx_window_scale;

/* make sure we don't receive anymore payload after FIN */
if ((fs->rx_base_sp & FLEXNIC_PL_FLOWST_RXFIN) == FLEXNIC_PL_FLOWST_RXFIN &&
Expand Down Expand Up @@ -631,7 +632,7 @@ int fast_flows_packet(struct dataplane_context *ctx,
/* if we need to send an ack, also send packet to TX pipeline to do so */
if (trigger_ack) {
flow_tx_ack(ctx, fs->tx_next_seq, fs->rx_next_seq, fs->rx_avail,
fs->tx_next_ts, ts, nbh, opts->ts);
fs->tx_next_ts, ts, fs->rx_window_scale, nbh, opts->ts);
}

fs_unlock(fs);
Expand Down Expand Up @@ -758,7 +759,7 @@ int fast_flows_bump(struct dataplane_context *ctx, uint32_t flow_id,
* we're not sending anyways. */
if (new_avail == 0 && rx_avail_prev == 0 && fs->rx_avail != 0) {
flow_tx_segment(ctx, nbh, fs, fs->tx_next_seq, fs->rx_next_seq,
fs->rx_avail, 0, 0, fs->tx_next_ts, ts, 0);
fs->rx_avail, 0, 0, fs->tx_next_ts, ts, fs->rx_window_scale, 0);
ret = 0;
}

Expand Down Expand Up @@ -877,7 +878,8 @@ static void flow_rx_seq_write(struct flextcp_pl_flowst *fs, uint32_t seq,
static void flow_tx_segment(struct dataplane_context *ctx,
struct network_buf_handle *nbh, struct flextcp_pl_flowst *fs,
uint32_t seq, uint32_t ack, uint32_t rxwnd, uint16_t payload,
uint32_t payload_pos, uint32_t ts_echo, uint32_t ts_my, uint8_t fin)
uint32_t payload_pos, uint32_t ts_echo, uint32_t ts_my,
uint8_t window_scale, uint8_t fin)
{
uint16_t hdrs_len, optlen, fin_fl;
struct pkt_tcp *p = network_buf_buf(nbh);
Expand Down Expand Up @@ -915,7 +917,7 @@ static void flow_tx_segment(struct dataplane_context *ctx,
p->tcp.seqno = t_beui32(seq);
p->tcp.ackno = t_beui32(ack);
TCPH_HDRLEN_FLAGS_SET(&p->tcp, 5 + optlen / 4, TCP_PSH | TCP_ACK | fin_fl);
p->tcp.wnd = t_beui16(MIN(0xFFFF, rxwnd));
p->tcp.wnd = t_beui16(MIN(0xFFFF, rxwnd >> window_scale));
p->tcp.chksum = 0;
p->tcp.urgp = t_beui16(0);

Expand Down Expand Up @@ -955,7 +957,7 @@ static void flow_tx_segment(struct dataplane_context *ctx,
}

static void flow_tx_ack(struct dataplane_context *ctx, uint32_t seq,
uint32_t ack, uint32_t rxwnd, uint32_t echots, uint32_t myts,
uint32_t ack, uint32_t rxwnd, uint32_t echots, uint32_t myts, uint8_t window_scale,
struct network_buf_handle *nbh, struct tcp_timestamp_opt *ts_opt)
{
struct pkt_tcp *p;
Expand Down Expand Up @@ -998,7 +1000,7 @@ static void flow_tx_ack(struct dataplane_context *ctx, uint32_t seq,
p->tcp.seqno = t_beui32(seq);
p->tcp.ackno = t_beui32(ack);
TCPH_HDRLEN_FLAGS_SET(&p->tcp, TCPH_HDRLEN(&p->tcp), TCP_ACK | ecn_flags);
p->tcp.wnd = t_beui16(MIN(0xFFFF, rxwnd));
p->tcp.wnd = t_beui16(MIN(0xFFFF, rxwnd >> window_scale));
p->tcp.urgp = t_beui16(0);

/* fill in timestamp option */
Expand Down
2 changes: 2 additions & 0 deletions tas/include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ struct configuration {
uint32_t tcp_handshake_to;
/** # of retries for dropped handshake packets */
uint32_t tcp_handshake_retries;
/** Window scale configuration */
uint8_t tcp_window_scale;
/** IP address for this host */
uint32_t ip;
/** IP prefix length for this host */
Expand Down
45 changes: 26 additions & 19 deletions tas/slow/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,32 +117,35 @@ enum nicif_connection_flags {
/**
* Register flow (must be called from poll thread).
*
* @param db Doorbell ID
* @param mac_remote MAC address of the remote host
* @param ip_local Local IP address
* @param port_local Local port number
* @param ip_remote Remote IP address
* @param port_remote Remote port number
* @param rx_base Base address of circular receive buffer
* @param rx_len Length of circular receive buffer
* @param tx_base Base address of circular transmit buffer
* @param tx_len Length of circular transmit buffer
* @param remote_seq Next sequence number expected from remote host
* @param local_seq Next sequence number for transmission
* @param app_opaque Opaque value to pass in notificaitions
* @param flags See #nicif_connection_flags.
* @param rate Congestion rate to set [Kbps]
* @param fn_core FlexNIC emulator core for the connection
* @param flow_group Flow group
* @param pf_id Pointer to location where flow id should be stored
* @param db Doorbell ID
* @param mac_remote MAC address of the remote host
* @param ip_local Local IP address
* @param port_local Local port number
* @param ip_remote Remote IP address
* @param port_remote Remote port number
* @param rx_base Base address of circular receive buffer
* @param rx_len Length of circular receive buffer
* @param tx_base Base address of circular transmit buffer
* @param tx_len Length of circular transmit buffer
* @param remote_seq Next sequence number expected from remote host
* @param local_seq Next sequence number for transmission
* @param app_opaque Opaque value to pass in notificaitions
* @param flags See #nicif_connection_flags.
* @param rate Congestion rate to set [Kbps]
* @param rx_window_scale Window scale factor for RX window
* @param tx_window_scale Window scale factor for TX window
* @param fn_core FlexNIC emulator core for the connection
* @param flow_group Flow group
* @param pf_id Pointer to location where flow id should be stored
*
* @return 0 on success, <0 else
*/
int nicif_connection_add(uint32_t db, uint64_t mac_remote, uint32_t ip_local,
uint16_t port_local, uint32_t ip_remote, uint16_t port_remote,
uint64_t rx_base, uint32_t rx_len, uint64_t tx_base, uint32_t tx_len,
uint32_t remote_seq, uint32_t local_seq, uint64_t app_opaque,
uint32_t flags, uint32_t rate, uint32_t fn_core, uint16_t flow_group,
uint32_t flags, uint32_t rate, uint8_t rx_window_scale, uint8_t tx_window_scale,
uint32_t fn_core, uint16_t flow_group,
uint32_t *pf_id);

/**
Expand Down Expand Up @@ -476,6 +479,10 @@ struct connection {
uint32_t local_seq;
/** Timestamp received with SYN/SYN-ACK packet */
uint32_t syn_ts;
/** TX Window scale factor */
uint8_t tx_window_scale;
/** RX Window scale factor */
uint8_t rx_window_scale;
/**@}*/

/**
Expand Down
5 changes: 4 additions & 1 deletion tas/slow/nicif.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ int nicif_connection_add(uint32_t db, uint64_t mac_remote, uint32_t ip_local,
uint16_t port_local, uint32_t ip_remote, uint16_t port_remote,
uint64_t rx_base, uint32_t rx_len, uint64_t tx_base, uint32_t tx_len,
uint32_t remote_seq, uint32_t local_seq, uint64_t app_opaque,
uint32_t flags, uint32_t rate, uint32_t fn_core, uint16_t flow_group,
uint32_t flags, uint32_t rate, uint8_t rx_window_scale, uint8_t tx_window_scale,
uint32_t fn_core, uint16_t flow_group,
uint32_t *pf_id)
{
struct flextcp_pl_flowst *fs;
Expand Down Expand Up @@ -222,6 +223,8 @@ int nicif_connection_add(uint32_t db, uint64_t mac_remote, uint32_t ip_local,
fs->flow_group = flow_group;
fs->lock = 0;
fs->bump_seq = 0;
fs->tx_window_scale = tx_window_scale;
fs->rx_window_scale = rx_window_scale;

fs->rx_avail = rx_len;
fs->rx_next_pos = 0;
Expand Down
Loading