Skip to content

Commit

Permalink
Implemented HOMA_GRO_SHORT_BYPASS policy
Browse files Browse the repository at this point in the history
  • Loading branch information
johnousterhout committed Dec 23, 2022
1 parent b2cdad6 commit 72ddcb6
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 6 deletions.
21 changes: 18 additions & 3 deletions homa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1874,17 +1874,32 @@ struct homa {
/* Bits that can be specified for gro_policy. These were created for
* testing, in order to evaluate various possible policies; you almost
* certainly should not use any value other than HOMA_GRO_NORMAL.
* If you want to know what the bits mean, read the code of
* homa_offload.c.
* HOMA_GRO_BYPASS: Pass all incoming packets directly to
* homa_softirq during GRO; this bypasses
* the SoftIRQ dispatching mechanism as well
* as the network and IP stack layers.
* HOMA_GRO_SAME_CORE If isolated packets arrive (not part of
* a batch) use the GRO core for SoftIRQ also.
* HOMA_GRO_IDLE Use old mechanism for selecting an idle
* core for SoftIRQ (deprecated).
* HOMA_GRO_NEXT Always use the next core in circular
* order for SoftIRQ (deprecated).
* HOMA_GRO_IDLE_NEW Use the new mechanism for selecting an
* idle core for SoftIRQ.
* HOMA_GRO_FAST_GRANTS Pass all grant I can see immediately to
* homa_softirq during GRO.
* HOMA_GRO_SHORT_BYPASS Pass all short packets directly to
* homa_softirq during GR).
*/
#define HOMA_GRO_BYPASS 1
#define HOMA_GRO_SAME_CORE 2
#define HOMA_GRO_IDLE 4
#define HOMA_GRO_NEXT 8
#define HOMA_GRO_IDLE_NEW 16
#define HOMA_GRO_FAST_GRANTS 32
#define HOMA_GRO_SHORT_BYPASS 64
#define HOMA_GRO_NORMAL (HOMA_GRO_SAME_CORE|HOMA_GRO_IDLE_NEW \
|HOMA_GRO_FAST_GRANTS)
|HOMA_GRO_SHORT_BYPASS)

/*
* @gro_busy_usecs: try not to schedule SoftIRQ processing on a core
Expand Down
4 changes: 3 additions & 1 deletion homa_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ struct sk_buff *homa_gro_receive(struct list_head *held_list,

core->last_active = get_cycles();

if (homa->gro_policy & HOMA_GRO_BYPASS) {
if ((homa->gro_policy & HOMA_GRO_BYPASS)
|| ((homa->gro_policy & HOMA_GRO_SHORT_BYPASS)
&& (skb->len < 1400))) {
homa_softirq(skb);

/* This return value indicates that we have freed skb. */
Expand Down
53 changes: 51 additions & 2 deletions test/unit_homa_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ FIXTURE_SETUP(homa_offload)
}
self->napi.gro_bitmask = 0;

self->skb = mock_skb_new(&self->ip, &self->header.common, 1400,
self->header.seg.offset);
self->skb = mock_skb_new(&self->ip, &self->header.common, 1400, 2000);
NAPI_GRO_CB(self->skb)->same_flow = 0;
NAPI_GRO_CB(self->skb)->last = self->skb;
NAPI_GRO_CB(self->skb)->count = 1;
Expand Down Expand Up @@ -87,6 +86,7 @@ FIXTURE_TEARDOWN(homa_offload)
unit_teardown();
}


TEST_F(homa_offload, homa_gro_receive__fast_grant_optimization)
{
struct in6_addr client_ip = unit_get_in_addr("196.168.0.1");
Expand Down Expand Up @@ -124,6 +124,55 @@ TEST_F(homa_offload, homa_gro_receive__fast_grant_optimization)
EXPECT_STREQ("", unit_log_get());
kfree_skb(skb);
}
TEST_F(homa_offload, homa_gro_receive__HOMA_GRO_SHORT_BYPASS)
{
struct in6_addr client_ip = unit_get_in_addr("196.168.0.1");
struct in6_addr server_ip = unit_get_in_addr("1.2.3.4");
int client_port = 40000;
int server_port = 99;
__u64 client_id = 1234;
__u64 server_id = 1235;
struct data_header h = {.common = {
.sport = htons(40000), .dport = htons(server_port),
.type = DATA,
.sender_id = cpu_to_be64(client_id)},
.message_length = htonl(10000),
.incoming = htonl(10000), .cutoff_version = 0,
.retransmit = 0,
.seg = {.offset = htonl(2000),
.segment_length = htonl(1400),
.ack = {0, 0, 0}}};
struct sk_buff *skb, *skb2, *skb3;

struct homa_rpc *srpc = unit_server_rpc(&self->hsk, UNIT_RCVD_ONE_PKT,
&client_ip, &server_ip, client_port, server_id, 10000,
200);
ASSERT_NE(NULL, srpc);
unit_log_clear();

/* First attempt: HOMA_GRO_SHORT_BYPASS not enabled. */
skb = mock_skb_new(&self->ip, &h.common, 1400, 2000);
struct sk_buff *result = homa_gro_receive(&self->empty_list, skb);
EXPECT_EQ(0, -PTR_ERR(result));
EXPECT_EQ(8600, srpc->msgin.bytes_remaining);

/* Second attempt: HOMA_GRO_SHORT_BYPASS enabled but packet too long. */
self->homa.gro_policy |= HOMA_GRO_SHORT_BYPASS;
skb2 = mock_skb_new(&self->ip, &h.common, 1400, 3000);
result = homa_gro_receive(&self->empty_list, skb2);
EXPECT_EQ(0, -PTR_ERR(result));
EXPECT_EQ(8600, srpc->msgin.bytes_remaining);

/* Third attempt: bypass should happen. */
h.seg.segment_length = htonl(100);
skb3 = mock_skb_new(&self->ip, &h.common, 100, 4000);
result = homa_gro_receive(&self->empty_list, skb3);
EXPECT_EQ(EINPROGRESS, -PTR_ERR(result));
EXPECT_EQ(8500, srpc->msgin.bytes_remaining);

kfree_skb(skb);
kfree_skb(skb2);
}
TEST_F(homa_offload, homa_gro_receive__no_held_skb)
{
struct sk_buff *skb;
Expand Down

0 comments on commit 72ddcb6

Please sign in to comment.