Skip to content

Commit

Permalink
Eliminate segment_length field of struct data_segment
Browse files Browse the repository at this point in the history
  • Loading branch information
johnousterhout committed Jul 29, 2024
1 parent ae32069 commit 0484a97
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 82 deletions.
13 changes: 10 additions & 3 deletions homa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,6 @@ struct data_segment {
*/
__be32 offset;

/** @segment_length: Number of bytes of data in this segment. */
__be32 segment_length;

/** @data: the payload of this segment. */
char data[0];
} __attribute__((packed));
Expand Down Expand Up @@ -422,6 +419,16 @@ _Static_assert(((sizeof(struct data_header) - sizeof(struct data_segment))
" data_header length not a multiple of 4 bytes (required "
"for TCP/TSO compatibility");

/**
* homa_rx_data_len() - Returns the total amount of message data contained
* in an incoming DATA packet. This function works only for incoming
* packets and ougoing packets that don't use GSO.
*/
static inline int homa_rx_data_len(struct sk_buff *skb)
{
return skb->len - skb_transport_offset(skb) - sizeof(struct data_header);
}

/**
* struct grant_header - Wire format for GRANT packets, which are sent by
* the receiver back to the sender to indicate that the sender may transmit
Expand Down
8 changes: 4 additions & 4 deletions homa_incoming.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void homa_add_packet(struct homa_rpc *rpc, struct sk_buff *skb)
{
struct data_header *h = (struct data_header *) skb->data;
int start = ntohl(h->seg.offset);
int length = ntohl(h->seg.segment_length);
int length = homa_rx_data_len(skb);
int end = start + length;
struct homa_gap *gap, *dummy, *gap2;

Expand Down Expand Up @@ -253,7 +253,7 @@ int homa_copy_to_user(struct homa_rpc *rpc)
struct data_header *h = (struct data_header *)
skbs[i]->data;
int offset = ntohl(h->seg.offset);
int pkt_length = ntohl(h->seg.segment_length);
int pkt_length = homa_rx_data_len(skbs[i]);
int copied = 0;
char *dst;
struct iovec iov;
Expand Down Expand Up @@ -574,9 +574,9 @@ void homa_data_pkt(struct sk_buff *skb, struct homa_rpc *rpc)
tt_record4("Dropping packet because no buffer space available: "
"id %d, offset %d, length %d, old incoming %d",
rpc->id, ntohl(h->seg.offset),
ntohl(h->seg.segment_length),
homa_rx_data_len(skb),
rpc->msgin.granted);
INC_METRIC(dropped_data_no_bufs, ntohl(h->seg.segment_length));
INC_METRIC(dropped_data_no_bufs, homa_rx_data_len(skb));
goto discard;
}

Expand Down
2 changes: 1 addition & 1 deletion homa_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ struct sk_buff *homa_gro_receive(struct list_head *held_list,
"id %llu, offset %d, priority %d",
saddr, homa_local_id(h_new->common.sender_id),
ntohl(h_new->seg.offset), priority);
if ((h_new->seg.segment_length == h_new->message_length)
if ((homa_rx_data_len(skb) == ntohl(h_new->message_length))
&& (homa->gro_policy & HOMA_GRO_SHORT_BYPASS)
&& !busy) {
INC_METRIC(gro_data_bypasses, 1);
Expand Down
33 changes: 19 additions & 14 deletions homa_outgoing.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ struct sk_buff *homa_new_data_packet(struct homa_rpc *rpc,
seg_size = bytes_left;
else
seg_size = max_seg_data;
seg.segment_length = htonl(seg_size);
err = homa_skb_append_to_frag(rpc->hsk->homa, skb, &seg,
sizeof(seg));
if (err != 0)
Expand Down Expand Up @@ -589,7 +588,7 @@ void homa_resend_data(struct homa_rpc *rpc, int start, int end,
*/
for (skb = rpc->msgout.packets; skb != NULL;
skb = homa_info->next_skb) {
int seg_offset, offset, length, segs_left;
int seg_offset, offset, seg_length, segs_left, data_left;
struct data_segment seg;
struct data_header *h;

Expand All @@ -602,21 +601,27 @@ void homa_resend_data(struct homa_rpc *rpc, int start, int end,
seg_offset = sizeof32(struct data_header)
- sizeof32(struct data_segment);
segs_left = skb_shinfo(skb)->gso_segs;
if (segs_left < 1)
data_left = homa_info->data_bytes;
if (segs_left < 1) {
segs_left = 1;
seg_length = homa_rx_data_len(skb);
} else
seg_length = skb_shinfo(skb)->gso_size - sizeof32(seg);
for ( ; segs_left > 0; segs_left--,
seg_offset += sizeof32(seg) + length) {
seg_offset += sizeof32(seg) + seg_length) {
struct sk_buff *new_skb;
struct homa_skb_info *new_homa_info;
int err;

homa_skb_get(skb, &seg, seg_offset, sizeof(seg));
offset = ntohl(seg.offset);
length = ntohl(seg.segment_length);
if (seg_length > data_left)
seg_length = data_left;
data_left -= seg_length;

if (end <= offset)
goto resend_done;
if ((offset + length) <= start)
if ((offset + seg_length) <= start)
continue;

/* This segment must be retransmitted. */
Expand All @@ -634,14 +639,14 @@ void homa_resend_data(struct homa_rpc *rpc, int start, int end,
sizeof32(struct data_header)
- sizeof32(struct data_segment));
h->retransmit = 1;
if ((offset + length) <= rpc->msgout.granted)
if ((offset + seg_length) <= rpc->msgout.granted)
h->incoming = htonl(rpc->msgout.granted);
else if ((offset + length) > rpc->msgout.length)
else if ((offset + seg_length) > rpc->msgout.length)
h->incoming = htonl(rpc->msgout.length);
else
h->incoming = htonl(offset + length);
h->incoming = htonl(offset + seg_length);
err = homa_skb_append_from_skb(rpc->hsk->homa, new_skb,
skb, seg_offset, sizeof32(seg) + length);
skb, seg_offset, sizeof32(seg) + seg_length);
if (err != 0) {
printk(KERN_ERR "homa_resend_data got error %d "
"from homa_skb_append_from_skb\n",
Expand All @@ -654,12 +659,12 @@ void homa_resend_data(struct homa_rpc *rpc, int start, int end,

new_homa_info = homa_get_skb_info(new_skb);
new_homa_info->wire_bytes = rpc->hsk->ip_header_length
+ sizeof(struct data_header) + length
+ HOMA_ETH_OVERHEAD;
new_homa_info->data_bytes = length;
+ sizeof(struct data_header)
+ seg_length + HOMA_ETH_OVERHEAD;
new_homa_info->data_bytes = seg_length;
new_homa_info->offset = offset;
tt_record3("retransmitting offset %d, length %d, id %d",
offset, length, rpc->id);
offset, seg_length, rpc->id);
homa_check_nic_queue(rpc->hsk->homa, new_skb, true);
__homa_xmit_data(new_skb, rpc, priority);
INC_METRIC(resent_packets, 1);
Expand Down
7 changes: 0 additions & 7 deletions homa_plumbing.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,13 +296,6 @@ static struct ctl_table homa_ctl_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "hijack_tcp",
.data = &homa_data.hijack_tcp,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "link_mbps",
.data = &homa_data.link_mbps,
Expand Down
51 changes: 36 additions & 15 deletions homa_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1126,8 +1126,18 @@ char *homa_print_packet(struct sk_buff *skb, char *buffer, int buf_len)
switch (common->type) {
case DATA: {
struct data_header *h = (struct data_header *) header;
int seg_length = ntohl(h->seg.segment_length);
int bytes_left, i;
struct homa_skb_info *homa_info = homa_get_skb_info(skb);
int data_left, i, seg_length, pos;
if (skb_shinfo(skb)->gso_segs == 0) {
seg_length = homa_rx_data_len(skb);
data_left = 0;
} else {
seg_length = skb_shinfo(skb)->gso_size
- sizeof(struct data_segment);
if (seg_length > homa_info->data_bytes)
seg_length = homa_info->data_bytes;
data_left = homa_info->data_bytes - seg_length;
}
used = homa_snprintf(buffer, buf_len, used,
", message_length %d, offset %d, "
"data_length %d, incoming %d",
Expand All @@ -1144,19 +1154,20 @@ char *homa_print_packet(struct sk_buff *skb, char *buffer, int buf_len)
if (skb_shinfo(skb)->gso_type == 0xd)
used = homa_snprintf(buffer, buf_len, used,
", TSO disabled");
bytes_left = skb->len - sizeof32(*h) - seg_length;
if (skb_shinfo(skb)->gso_segs <= 1)
break;
pos = skb_transport_offset(skb) + sizeof32(*h) + seg_length;
used = homa_snprintf(buffer, buf_len, used, ", extra segs");
for (i = skb_shinfo(skb)->gso_segs - 1; i > 0; i--) {
struct data_segment seg;
homa_skb_get(skb, &seg, skb->len - bytes_left,
sizeof(seg));
seg_length = ntohl(seg.segment_length);
homa_skb_get(skb, &seg, pos, sizeof(seg));
if (seg_length > data_left)
seg_length = data_left;
used = homa_snprintf(buffer, buf_len, used,
" %d@%d", seg_length,
ntohl(seg.offset));
bytes_left -= sizeof32(seg) + seg_length;
data_left -= seg_length;
pos += seg_length + sizeof(struct data_segment);
};
break;
}
Expand Down Expand Up @@ -1241,23 +1252,33 @@ char *homa_print_packet_short(struct sk_buff *skb, char *buffer, int buf_len)
homa_skb_get(skb, header, 0, HOMA_MAX_HEADER);
switch (common->type) {
case DATA: {
struct data_header *h = (struct data_header *) header;
struct data_header *h = (struct data_header *)header;
struct homa_skb_info *homa_info = homa_get_skb_info(skb);
struct data_segment seg;
int bytes_left, used, i;
int seg_length = ntohl(h->seg.segment_length);
int data_left, used, i, seg_length, pos;
if (skb_shinfo(skb)->gso_segs == 0) {
seg_length = homa_rx_data_len(skb);
data_left = 0;
} else {
seg_length = skb_shinfo(skb)->gso_size - sizeof32(seg);
if (seg_length > homa_info->data_bytes)
seg_length = homa_info->data_bytes;
data_left = homa_info->data_bytes - seg_length;
}

pos = skb_transport_offset(skb) + sizeof32(*h) + seg_length;
used = homa_snprintf(buffer, buf_len, 0, "DATA%s %d@%d",
h->retransmit ? " retrans" : "",
seg_length, ntohl(h->seg.offset));
bytes_left = skb->len - sizeof32(*h) - seg_length;
for (i = skb_shinfo(skb)->gso_segs - 1; i > 0; i--) {
homa_skb_get(skb, &seg, skb->len - bytes_left,
sizeof(seg));
seg_length = ntohl(seg.segment_length);
homa_skb_get(skb, &seg, pos, sizeof(seg));
if (seg_length > data_left)
seg_length = data_left;
used = homa_snprintf(buffer, buf_len, used,
" %d@%d", seg_length,
ntohl(seg.offset));
bytes_left -= sizeof32(seg) + seg_length;
data_left -= seg_length;
pos += seg_length + sizeof32(struct data_segment);
}
break;
}
Expand Down
3 changes: 1 addition & 2 deletions test/mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1024,8 +1024,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
/* Split the existing packet into two packets. */
memcpy(&h, skb_transport_header(head_skb), sizeof(h));
offset = ntohl(h.seg.offset);
length = ntohl(h.seg.segment_length);
h.seg.segment_length = htonl(length/2);
length = homa_rx_data_len(head_skb);
skb1 = mock_skb_new(&ipv6_hdr(head_skb)->saddr, &h.common, length/2,
offset);
offset += length/2;
Expand Down
2 changes: 1 addition & 1 deletion test/unit_homa_grant.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ FIXTURE_SETUP(homa_grant)
.incoming = htonl(10000), .cutoff_version = 0,
.ack = {0, 0, 0},
.retransmit = 0,
.seg = {.offset = 0, .segment_length = htonl(1400)}};
.seg = {.offset = 0}};
unit_log_clear();
self->incoming_delta = 0;
}
Expand Down
12 changes: 3 additions & 9 deletions test/unit_homa_incoming.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ FIXTURE_SETUP(homa_incoming)
.incoming = htonl(10000), .cutoff_version = 0,
.ack = {0, 0, 0},
.retransmit = 0,
.seg = {.offset = 0, .segment_length = htonl(1400)}};
.seg = {.offset = 0}};
unit_log_clear();
delete_count = 0;
lock_delete_count = 0;
Expand Down Expand Up @@ -260,7 +260,6 @@ TEST_F(homa_incoming, homa_add_packet__basics)
&self->data.common, 1400, 1400));

self->data.seg.offset = htonl(4200);
self->data.seg.segment_length = htonl(800);
homa_add_packet(crpc, mock_skb_new(self->client_ip,
&self->data.common, 800, 4200));
EXPECT_STREQ("start 0, end 1400, time 5000; "
Expand All @@ -269,7 +268,6 @@ TEST_F(homa_incoming, homa_add_packet__basics)

unit_log_clear();
self->data.seg.offset = 0;
self->data.seg.segment_length = htonl(1400);
homa_add_packet(crpc, mock_skb_new(self->client_ip,
&self->data.common, 1400, 0));
EXPECT_STREQ("start 2800, end 4200, time 5000", unit_print_gaps(crpc));
Expand Down Expand Up @@ -601,9 +599,8 @@ TEST_F(homa_incoming, homa_copy_to_user__basics)
homa_data_pkt(mock_skb_new(self->server_ip, &self->data.common,
1400, 101000), crpc);
self->data.seg.offset = htonl(2800);
self->data.seg.segment_length = htonl(1200);
homa_data_pkt(mock_skb_new(self->server_ip, &self->data.common,
1400, 201800), crpc);
1200, 201800), crpc);

unit_log_clear();
mock_copy_to_user_dont_copy = -1;
Expand Down Expand Up @@ -691,7 +688,6 @@ TEST_F(homa_incoming, homa_copy_to_user__many_chunks_for_one_skb)
1000, 4000);
ASSERT_NE(NULL, crpc);
self->data.message_length = htonl(4000);
self->data.seg.segment_length = htonl(3000);
homa_data_pkt(mock_skb_new(self->server_ip, &self->data.common,
3000, 101000), crpc);

Expand Down Expand Up @@ -1120,7 +1116,6 @@ TEST_F(homa_incoming, homa_data_pkt__wrong_client_rpc_state)
crpc->state = RPC_DEAD;
self->data.message_length = htonl(2000);
self->data.seg.offset = htonl(1400);
self->data.seg.segment_length = htonl(600);
homa_data_pkt(mock_skb_new(self->server_ip, &self->data.common,
600, 1400), crpc);
EXPECT_EQ(600, crpc->msgin.bytes_remaining);
Expand Down Expand Up @@ -1226,10 +1221,9 @@ TEST_F(homa_incoming, homa_data_pkt__handoff)
*/
self->data.message_length = htonl(3000);
self->data.seg.offset = htonl(2800);
self->data.seg.segment_length = htonl(200);
unit_log_clear();
homa_data_pkt(mock_skb_new(self->server_ip, &self->data.common,
1400, 0), crpc);
200, 0), crpc);
EXPECT_STREQ("", unit_log_get());
}
TEST_F(homa_incoming, homa_data_pkt__send_cutoffs)
Expand Down
10 changes: 4 additions & 6 deletions test/unit_homa_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ FIXTURE_SETUP(homa_offload)
.incoming = htonl(10000), .cutoff_version = 0,
.ack = {0, 0, 0},
.retransmit = 0,
.seg = {.offset = htonl(2000),
.segment_length = htonl(1400)}};
.seg = {.offset = htonl(2000)}};
for (i = 0; i < GRO_HASH_BUCKETS; i++) {
INIT_LIST_HEAD(&self->napi.gro_hash[i].list);
self->napi.gro_hash[i].count = 0;
Expand Down Expand Up @@ -227,8 +226,7 @@ TEST_F(homa_offload, homa_gro_receive__HOMA_GRO_SHORT_BYPASS)
.incoming = htonl(10000), .cutoff_version = 0,
.ack = {0, 0, 0},
.retransmit = 0,
.seg = {.offset = htonl(2000),
.segment_length = htonl(1400)}};
.seg = {.offset = htonl(2000)}};
struct sk_buff *skb, *skb2, *skb3, *skb4;

struct homa_rpc *srpc = unit_server_rpc(&self->hsk, UNIT_RCVD_ONE_PKT,
Expand All @@ -254,8 +252,8 @@ TEST_F(homa_offload, homa_gro_receive__HOMA_GRO_SHORT_BYPASS)
EXPECT_EQ(0, homa_cores[cpu_number]->metrics.gro_data_bypasses);

/* Third attempt: bypass should happen. */
h.message_length = h.seg.segment_length;
h.incoming = h.seg.segment_length;
h.message_length = htonl(1400);
h.incoming = htonl(1400);
homa_cores[cpu_number]->last_gro = 400;
skb3 = mock_skb_new(&self->ip, &h.common, 1400, 4000);
result = homa_gro_receive(&self->empty_list, skb3);
Expand Down
Loading

0 comments on commit 0484a97

Please sign in to comment.