TAS
TCP Acceleration as an OS Service
fast_appctx.c
1 /*
2  * Copyright 2019 University of Washington, Max Planck Institute for
3  * Software Systems, and The University of Texas at Austin
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <assert.h>
26 #include <rte_config.h>
27 
28 #include <tas_memif.h>
29 
30 #include "internal.h"
31 #include "fastemu.h"
32 
33 void fast_appctx_poll_pf(struct dataplane_context *ctx, uint32_t id)
34 {
35  struct flextcp_pl_appctx *actx = &fp_state->appctx[ctx->id][id];
36  rte_prefetch0(dma_pointer(actx->tx_base + actx->tx_head, 1));
37 }
38 
39 int fast_appctx_poll_fetch(struct dataplane_context *ctx, uint32_t id,
40  void **pqe)
41 {
42  struct flextcp_pl_appctx *actx = &fp_state->appctx[ctx->id][id];
43  struct flextcp_pl_atx *atx;
44  uint8_t type;
45  uint32_t flow_id = -1;
46 
47  /* stop if context is not in use */
48  if (actx->tx_len == 0)
49  return -1;
50 
51  atx = dma_pointer(actx->tx_base + actx->tx_head, sizeof(*atx));
52 
53  type = atx->type;
54  MEM_BARRIER();
55 
56  if (type == 0) {
57  return -1;
58  } else if (type != FLEXTCP_PL_ATX_CONNUPDATE) {
59  fprintf(stderr, "fast_appctx_poll: unknown type: %u id=%u\n", type,
60  id);
61  abort();
62  }
63 
64  *pqe = atx;
65 
66  /* update RX/TX queue pointers for connection */
67  flow_id = atx->msg.connupdate.flow_id;
68  if (flow_id >= FLEXNIC_PL_FLOWST_NUM) {
69  fprintf(stderr, "fast_appctx_poll: invalid flow id=%u\n", flow_id);
70  abort();
71  }
72 
73  void *fs = &fp_state->flowst[flow_id];
74  rte_prefetch0(fs);
75  rte_prefetch0(fs + 64);
76 
77  actx->tx_head += sizeof(*atx);
78  if (actx->tx_head >= actx->tx_len)
79  actx->tx_head -= actx->tx_len;
80 
81  return 0;
82 }
83 
84 int fast_appctx_poll_bump(struct dataplane_context *ctx, void *pqe,
85  struct network_buf_handle *nbh, uint32_t ts)
86 {
87  struct flextcp_pl_atx *atx = pqe;
88  int ret;
89 
90  ret = fast_flows_bump(ctx, atx->msg.connupdate.flow_id,
91  atx->msg.connupdate.bump_seq, atx->msg.connupdate.rx_bump,
92  atx->msg.connupdate.tx_bump, atx->msg.connupdate.flags, nbh, ts);
93 
94  if (ret != 0)
95  ret = 1;
96 
97  MEM_BARRIER();
98  atx->type = 0;
99 
100  return ret;
101 }
102 
103 void fast_actx_rxq_pf(struct dataplane_context *ctx,
104  struct flextcp_pl_appctx *actx)
105 {
106 
107  rte_prefetch0(dma_pointer(actx->rx_base + actx->rx_head,
108  sizeof(struct flextcp_pl_arx)));
109 }
110 
111 
112 int fast_actx_rxq_alloc(struct dataplane_context *ctx,
113  struct flextcp_pl_appctx *actx, struct flextcp_pl_arx **arx)
114 {
115  struct flextcp_pl_arx *parx;
116  uint32_t rxnhead;
117  int ret = 0;
118 
119  if (actx->rx_avail == 0) {
120  return -1;
121  }
122 
123  MEM_BARRIER();
124  parx = dma_pointer(actx->rx_base + actx->rx_head, sizeof(*parx));
125 
126  rxnhead = actx->rx_head + sizeof(*parx);
127  if (rxnhead >= actx->rx_len) {
128  rxnhead -= actx->rx_len;
129  }
130  actx->rx_head = rxnhead;
131  actx->rx_avail -= sizeof(*parx);
132 
133  *arx = parx;
134  return ret;
135 }
136 
137 
138 int fast_actx_rxq_probe(struct dataplane_context *ctx, uint32_t id)
139 {
140  struct flextcp_pl_appctx *actx = &fp_state->appctx[ctx->id][id];
141  struct flextcp_pl_arx *parx;
142  uint32_t pos, i;
143 
144  if (actx->rx_avail > actx->rx_len / 2) {
145  return -1;
146  }
147 
148  pos = actx->rx_head + actx->rx_avail;
149  if (pos >= actx->rx_len)
150  pos -= actx->rx_len;
151 
152  i = 0;
153  while (actx->rx_avail < actx->rx_len && i < 2 * BATCH_SIZE) {
154  parx = dma_pointer(actx->rx_base + pos, sizeof(*parx));
155 
156  if (parx->type != 0) {
157  break;
158  }
159 
160  actx->rx_avail += sizeof(*parx);
161  pos += sizeof(*parx);
162  if (pos >= actx->rx_len)
163  pos -= actx->rx_len;
164  i++;
165 
166  MEM_BARRIER();
167  }
168 
169  return 0;
170 }