FD.io VPP  v16.06
Vector Packet Processing
dpdk_priv.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define DPDK_NB_RX_DESC_DEFAULT 512
17 #define DPDK_NB_TX_DESC_DEFAULT 512
18 #define DPDK_NB_RX_DESC_VIRTIO 256
19 #define DPDK_NB_TX_DESC_VIRTIO 256
20 #define DPDK_NB_RX_DESC_10GE 2048
21 #define DPDK_NB_TX_DESC_10GE 2048
22 #define DPDK_NB_RX_DESC_40GE (4096-128)
23 #define DPDK_NB_TX_DESC_40GE 2048
24 #define DPDK_NB_RX_DESC_ENIC (4096+1024)
25 
26 /* These args appear by themselves */
27 #define foreach_eal_double_hyphen_predicate_arg \
28 _(no-shconf) \
29 _(no-hpet) \
30 _(no-pci) \
31 _(no-huge) \
32 _(vmware-tsc-map) \
33 _(virtio-vhost)
34 
35 #define foreach_eal_single_hyphen_mandatory_arg \
36 _(coremask, c) \
37 _(nchannels, n) \
38 
39 #define foreach_eal_single_hyphen_arg \
40 _(blacklist, b) \
41 _(mem-alloc-request, m) \
42 _(force-ranks, r)
43 
44 /* These args are preceeded by "--" and followed by a single string */
45 #define foreach_eal_double_hyphen_arg \
46 _(huge-dir) \
47 _(proc-type) \
48 _(file-prefix) \
49 _(vdev)
50 
51 static inline u32
52 dpdk_rx_burst ( dpdk_main_t * dm, dpdk_device_t * xd, u16 queue_id)
53 {
54  u32 n_buffers;
55  u32 n_left;
56  u32 n_this_chunk;
57 
58  n_left = VLIB_FRAME_SIZE;
59  n_buffers = 0;
60 
62  {
63  while (n_left)
64  {
65  n_this_chunk = rte_eth_rx_burst (xd->device_index, queue_id,
66  xd->rx_vectors[queue_id] + n_buffers, n_left);
67  n_buffers += n_this_chunk;
68  n_left -= n_this_chunk;
69 
70  /* Empirically, DPDK r1.8 produces vectors w/ 32 or fewer elts */
71  if (n_this_chunk < 32)
72  break;
73  }
74  }
75  else if (xd->dev_type == VNET_DPDK_DEV_VHOST_USER)
76  {
77  vlib_main_t * vm = vlib_get_main();
79  unsigned socket_id = rte_socket_id();
80  u32 offset = 0;
81 
82 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0)
83  offset = queue_id * VIRTIO_QNUM;
84 
85  struct vhost_virtqueue *vq =
86  xd->vu_vhost_dev.virtqueue[offset + VIRTIO_TXQ];
87 
88  if (PREDICT_FALSE(!vq->enabled))
89  return 0;
90 #else
91  if (PREDICT_FALSE(!xd->vu_is_running))
92  return 0;
93 #endif
94 
95  n_buffers = rte_vhost_dequeue_burst(&xd->vu_vhost_dev, offset + VIRTIO_TXQ,
96  bm->pktmbuf_pools[socket_id],
97  xd->rx_vectors[queue_id], VLIB_FRAME_SIZE);
98 
99  int i; u32 bytes = 0;
100  struct rte_mbuf **pkts = xd->rx_vectors[queue_id];
101  for (i = 0; i < n_buffers; i++) {
102  struct rte_mbuf *buff = pkts[i];
103  bytes += rte_pktmbuf_data_len(buff);
104  }
105 
106  f64 now = vlib_time_now (vm);
107 
108  dpdk_vu_vring *vring = NULL;
109  /* send pending interrupts if needed */
110  if (dpdk_vhost_user_want_interrupt(xd, offset + VIRTIO_TXQ)) {
111  vring = &(xd->vu_intf->vrings[offset + VIRTIO_TXQ]);
112  vring->n_since_last_int += n_buffers;
113 
114  if ((vring->n_since_last_int && (vring->int_deadline < now))
115  || (vring->n_since_last_int > dm->vhost_coalesce_frames))
116  dpdk_vhost_user_send_interrupt(vm, xd, offset + VIRTIO_TXQ);
117  }
118 
119  vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
120  vring->packets += n_buffers;
121  vring->bytes += bytes;
122 
123  if (dpdk_vhost_user_want_interrupt(xd, offset + VIRTIO_RXQ)) {
124  if (vring->n_since_last_int && (vring->int_deadline < now))
125  dpdk_vhost_user_send_interrupt(vm, xd, offset + VIRTIO_RXQ);
126  }
127 
128  }
129 #ifdef RTE_LIBRTE_KNI
130  else if (xd->dev_type == VNET_DPDK_DEV_KNI)
131  {
132  n_buffers = rte_kni_rx_burst(xd->kni, xd->rx_vectors[queue_id], VLIB_FRAME_SIZE);
133  rte_kni_handle_request(xd->kni);
134  }
135 #endif
136  else
137  {
138  ASSERT(0);
139  }
140 
141  return n_buffers;
142 }
143 
144 
145 static inline void
147 {
148  int len;
149  if ((len = rte_eth_xstats_get(xd->device_index, NULL, 0)) > 0)
150  {
151  vec_validate(xd->xstats, len - 1);
152  vec_validate(xd->last_cleared_xstats, len - 1);
153 
154  len = rte_eth_xstats_get(xd->device_index, xd->xstats, vec_len(xd->xstats));
155 
156  ASSERT(vec_len(xd->xstats) == len);
157  ASSERT(vec_len(xd->last_cleared_xstats) == len);
158 
159  _vec_len(xd->xstats) = len;
160  _vec_len(xd->last_cleared_xstats) = len;
161 
162  }
163 }
164 
165 
166 static inline void
168 {
170  vnet_main_t * vnm = vnet_get_main();
171  u32 my_cpu = os_get_cpu_number();
172  u64 rxerrors, last_rxerrors;
173 
174  /* only update counters for PMD interfaces */
175  if (xd->dev_type != VNET_DPDK_DEV_ETH)
176  return;
177 
178  /*
179  * DAW-FIXME: VMXNET3 device stop/start doesn't work,
180  * therefore fake the stop in the dpdk driver by
181  * silently dropping all of the incoming pkts instead of
182  * stopping the driver / hardware.
183  */
184  if (xd->admin_up != 0xff)
185  {
186  xd->time_last_stats_update = now ? now : xd->time_last_stats_update;
187  clib_memcpy (&xd->last_stats, &xd->stats, sizeof (xd->last_stats));
188  rte_eth_stats_get (xd->device_index, &xd->stats);
189 
190  /* maybe bump interface rx no buffer counter */
191  if (PREDICT_FALSE (xd->stats.rx_nombuf != xd->last_stats.rx_nombuf))
192  {
195 
197  xd->stats.rx_nombuf -
198  xd->last_stats.rx_nombuf);
199  }
200 
201  /* missed pkt counter */
202  if (PREDICT_FALSE (xd->stats.imissed != xd->last_stats.imissed))
203  {
206 
208  xd->stats.imissed -
209  xd->last_stats.imissed);
210  }
211 #if RTE_VERSION >= RTE_VERSION_NUM(2, 2, 0, 0)
212  rxerrors = xd->stats.ierrors;
213  last_rxerrors = xd->last_stats.ierrors;
214 #else
215  rxerrors = xd->stats.ibadcrc
216  + xd->stats.ibadlen + xd->stats.ierrors;
217  last_rxerrors = xd->last_stats.ibadcrc
218  + xd->last_stats.ibadlen + xd->last_stats.ierrors;
219 #endif
220 
221  if (PREDICT_FALSE (rxerrors != last_rxerrors))
222  {
225 
227  rxerrors - last_rxerrors);
228  }
229  }
230 
231  dpdk_get_xstats(xd);
232 }
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:394
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
u32 n_since_last_int
Definition: dpdk.h:147
struct rte_eth_stats last_stats
Definition: dpdk.h:249
void dpdk_vhost_user_send_interrupt(vlib_main_t *vm, dpdk_device_t *xd, int idx)
Definition: vhost_user.c:852
vnet_interface_main_t interface_main
Definition: vnet.h:62
#define PREDICT_TRUE(x)
Definition: clib.h:98
#define NULL
Definition: clib.h:55
u32 vhost_coalesce_frames
Definition: dpdk.h:376
struct virtio_net vu_vhost_dev
Definition: dpdk.h:238
vlib_buffer_main_t * buffer_main
Definition: main.h:103
u64 packets
Definition: dpdk.h:149
always_inline vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u8 admin_up
Definition: dpdk.h:218
struct rte_eth_stats stats
Definition: dpdk.h:248
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
u8 dpdk_vhost_user_want_interrupt(dpdk_device_t *xd, int idx)
Definition: vhost_user.c:836
dpdk_vu_vring vrings[VHOST_MAX_QUEUE_PAIRS *2]
Definition: dpdk.h:166
u32 vu_is_running
Definition: dpdk.h:239
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
unsigned long u64
Definition: types.h:89
static void dpdk_get_xstats(dpdk_device_t *xd)
Definition: dpdk_priv.h:146
u32 device_index
Definition: dpdk.h:193
struct rte_eth_xstats * last_cleared_xstats
Definition: dpdk.h:252
f64 time_last_stats_update
Definition: dpdk.h:253
u32 vlib_sw_if_index
Definition: dpdk.h:196
always_inline void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 cpu_index, u32 index, u32 increment)
Definition: counter.h:70
uword os_get_cpu_number(void)
Definition: unix-misc.c:206
u64 bytes
Definition: dpdk.h:150
#define PREDICT_FALSE(x)
Definition: clib.h:97
#define VLIB_FRAME_SIZE
Definition: node.h:292
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:457
static void dpdk_update_counters(dpdk_device_t *xd, f64 now)
Definition: dpdk_priv.h:167
struct rte_kni * kni
Definition: dpdk.h:233
struct rte_mbuf *** rx_vectors
Definition: dpdk.h:203
#define clib_memcpy(a, b, c)
Definition: string.h:63
f64 int_deadline
Definition: dpdk.h:148
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
unsigned short u16
Definition: types.h:57
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:140
dpdk_device_type_t dev_type
Definition: dpdk.h:214
static u32 dpdk_rx_burst(dpdk_main_t *dm, dpdk_device_t *xd, u16 queue_id)
Definition: dpdk_priv.h:52
struct rte_eth_xstats * xstats
Definition: dpdk.h:251
always_inline f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:182
dpdk_vu_intf_t * vu_intf
Definition: dpdk.h:240