Skip to content

Commit 09c7e63

Browse files
Jakub GrajciarFerruh Yigit
Jakub Grajciar
authored and
Ferruh Yigit
committed
net/memif: introduce memory interface PMD
Shared memory packet interface (memif) PMD allows for DPDK and any other client using memif (DPDK, VPP, libmemif) to communicate using shared memory. The created device transmits packets in a raw format. It can be used with Ethernet mode, IP mode, or Punt/Inject. At this moment, only Ethernet mode is supported in DPDK memif implementation. Memif is Linux only. Signed-off-by: Jakub Grajciar <[email protected]> Reviewed-by: Ferruh Yigit <[email protected]>
1 parent fce0663 commit 09c7e63

18 files changed

+3143
-0
lines changed

MAINTAINERS

+6
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,12 @@ F: drivers/net/softnic/
839839
F: doc/guides/nics/features/softnic.ini
840840
F: doc/guides/nics/softnic.rst
841841

842+
Memif PMD
843+
M: Jakub Grajciar <[email protected]>
844+
F: drivers/net/memif/
845+
F: doc/guides/nics/memif.rst
846+
F: doc/guides/nics/features/memif.ini
847+
842848

843849
Crypto Drivers
844850
--------------

config/common_base

+5
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,11 @@ CONFIG_RTE_LIBRTE_PMD_AF_PACKET=n
444444
#
445445
CONFIG_RTE_LIBRTE_PMD_AF_XDP=n
446446

447+
#
448+
# Compile Memory Interface PMD driver (Linux only)
449+
#
450+
CONFIG_RTE_LIBRTE_PMD_MEMIF=n
451+
447452
#
448453
# Compile link bonding PMD library
449454
#

config/common_linux

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ CONFIG_RTE_LIBRTE_VHOST_POSTCOPY=n
1919
CONFIG_RTE_LIBRTE_PMD_VHOST=y
2020
CONFIG_RTE_LIBRTE_IFC_PMD=y
2121
CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
22+
CONFIG_RTE_LIBRTE_PMD_MEMIF=y
2223
CONFIG_RTE_LIBRTE_PMD_SOFTNIC=y
2324
CONFIG_RTE_LIBRTE_PMD_TAP=y
2425
CONFIG_RTE_LIBRTE_AVP_PMD=y

doc/guides/nics/features/memif.ini

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
;
2+
; Supported features of the 'memif' network poll mode driver.
3+
;
4+
; Refer to default.ini for the full list of available PMD features.
5+
;
6+
[Features]
7+
Link status = Y
8+
Basic stats = Y
9+
Jumbo frame = Y
10+
ARMv8 = Y
11+
Power8 = Y
12+
x86-32 = Y
13+
x86-64 = Y
14+
Usage doc = Y

doc/guides/nics/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Network Interface Controller Drivers
3636
intel_vf
3737
kni
3838
liquidio
39+
memif
3940
mlx4
4041
mlx5
4142
mvneta

doc/guides/nics/memif.rst

+234
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
.. SPDX-License-Identifier: BSD-3-Clause
2+
Copyright(c) 2018-2019 Cisco Systems, Inc.
3+
4+
======================
5+
Memif Poll Mode Driver
6+
======================
7+
8+
Shared memory packet interface (memif) PMD allows for DPDK and any other client
9+
using memif (DPDK, VPP, libmemif) to communicate using shared memory. Memif is
10+
Linux only.
11+
12+
The created device transmits packets in a raw format. It can be used with
13+
Ethernet mode, IP mode, or Punt/Inject. At this moment, only Ethernet mode is
14+
supported in DPDK memif implementation.
15+
16+
Memif works in two roles: master and slave. Slave connects to master over an
17+
existing socket. It is also a producer of shared memory file and initializes
18+
the shared memory. Each interface can be connected to one peer interface
19+
at same time. The peer interface is identified by id parameter. Master
20+
creates the socket and listens for any slave connection requests. The socket
21+
may already exist on the system. Be sure to remove any such sockets, if you
22+
are creating a master interface, or you will see an "Address already in use"
23+
error. Function ``rte_pmd_memif_remove()``, which removes memif interface,
24+
will also remove a listener socket, if it is not being used by any other
25+
interface.
26+
27+
The method to enable one or more interfaces is to use the
28+
``--vdev=net_memif0`` option on the DPDK application command line. Each
29+
``--vdev=net_memif1`` option given will create an interface named net_memif0,
30+
net_memif1, and so on. Memif uses unix domain socket to transmit control
31+
messages. Each memif has a unique id per socket. This id is used to identify
32+
peer interface. If you are connecting multiple
33+
interfaces using same socket, be sure to specify unique ids ``id=0``, ``id=1``,
34+
etc. Note that if you assign a socket to a master interface it becomes a
35+
listener socket. Listener socket can not be used by a slave interface on same
36+
client.
37+
38+
.. csv-table:: **Memif configuration options**
39+
:header: "Option", "Description", "Default", "Valid value"
40+
41+
"id=0", "Used to identify peer interface", "0", "uint32_t"
42+
"role=master", "Set memif role", "slave", "master|slave"
43+
"bsize=1024", "Size of single packet buffer", "2048", "uint16_t"
44+
"rsize=11", "Log2 of ring size. If rsize is 10, actual ring size is 1024", "10", "1-14"
45+
"socket=/tmp/memif.sock", "Socket filename", "/tmp/memif.sock", "string len 256"
46+
"mac=01:23:45:ab:cd:ef", "Mac address", "01:ab:23:cd:45:ef", ""
47+
"secret=abc123", "Secret is an optional security option, which if specified, must be matched by peer", "", "string len 24"
48+
"zero-copy=yes", "Enable/disable zero-copy slave mode", "no", "yes|no"
49+
50+
**Connection establishment**
51+
52+
In order to create memif connection, two memif interfaces, each in separate
53+
process, are needed. One interface in ``master`` role and other in
54+
``slave`` role. It is not possible to connect two interfaces in a single
55+
process. Each interface can be connected to one interface at same time,
56+
identified by matching id parameter.
57+
58+
Memif driver uses unix domain socket to exchange required information between
59+
memif interfaces. Socket file path is specified at interface creation see
60+
*Memif configuration options* table above. If socket is used by ``master``
61+
interface, it's marked as listener socket (in scope of current process) and
62+
listens to connection requests from other processes. One socket can be used by
63+
multiple interfaces. One process can have ``slave`` and ``master`` interfaces
64+
at the same time, provided each role is assigned unique socket.
65+
66+
For detailed information on memif control messages, see: net/memif/memif.h.
67+
68+
Slave interface attempts to make a connection on assigned socket. Process
69+
listening on this socket will extract the connection request and create a new
70+
connected socket (control channel). Then it sends the 'hello' message
71+
(``MEMIF_MSG_TYPE_HELLO``), containing configuration boundaries. Slave interface
72+
adjusts its configuration accordingly, and sends 'init' message
73+
(``MEMIF_MSG_TYPE_INIT``). This message among others contains interface id. Driver
74+
uses this id to find master interface, and assigns the control channel to this
75+
interface. If such interface is found, 'ack' message (``MEMIF_MSG_TYPE_ACK``) is
76+
sent. Slave interface sends 'add region' message (``MEMIF_MSG_TYPE_ADD_REGION``) for
77+
every region allocated. Master responds to each of these messages with 'ack'
78+
message. Same behavior applies to rings. Slave sends 'add ring' message
79+
(``MEMIF_MSG_TYPE_ADD_RING``) for every initialized ring. Master again responds to
80+
each message with 'ack' message. To finalize the connection, slave interface
81+
sends 'connect' message (``MEMIF_MSG_TYPE_CONNECT``). Upon receiving this message
82+
master maps regions to its address space, initializes rings and responds with
83+
'connected' message (``MEMIF_MSG_TYPE_CONNECTED``). Disconnect
84+
(``MEMIF_MSG_TYPE_DISCONNECT``) can be sent by both master and slave interfaces at
85+
any time, due to driver error or if the interface is being deleted.
86+
87+
Files
88+
89+
- net/memif/memif.h *- control messages definitions*
90+
- net/memif/memif_socket.h
91+
- net/memif/memif_socket.c
92+
93+
Shared memory
94+
~~~~~~~~~~~~~
95+
96+
**Shared memory format**
97+
98+
Slave is producer and master is consumer. Memory regions, are mapped shared memory files,
99+
created by memif slave and provided to master at connection establishment.
100+
Regions contain rings and buffers. Rings and buffers can also be separated into multiple
101+
regions. For no-zero-copy, rings and buffers are stored inside single memory
102+
region to reduce the number of opened files.
103+
104+
region n (no-zero-copy):
105+
106+
+-----------------------+-------------------------------------------------------------------------+
107+
| Rings | Buffers |
108+
+-----------+-----------+-----------------+---+---------------------------------------------------+
109+
| S2M rings | M2S rings | packet buffer 0 | . | pb ((1 << pmd->run.log2_ring_size)*(s2m + m2s))-1 |
110+
+-----------+-----------+-----------------+---+---------------------------------------------------+
111+
112+
S2M OR M2S Rings:
113+
114+
+--------+--------+-----------------------+
115+
| ring 0 | ring 1 | ring num_s2m_rings - 1|
116+
+--------+--------+-----------------------+
117+
118+
ring 0:
119+
120+
+-------------+---------------------------------------+
121+
| ring header | (1 << pmd->run.log2_ring_size) * desc |
122+
+-------------+---------------------------------------+
123+
124+
Descriptors are assigned packet buffers in order of rings creation. If we have one ring
125+
in each direction and ring size is 1024, then first 1024 buffers will belong to S2M ring and
126+
last 1024 will belong to M2S ring. In case of zero-copy, buffers are dequeued and
127+
enqueued as needed.
128+
129+
**Descriptor format**
130+
131+
+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
132+
|Quad|6| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |3|3| | | | | | | | | | | | | | |1|1| | | | | | | | | | | | | | | |
133+
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
134+
|Word|3| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |2|1| | | | | | | | | | | | | | |6|5| | | | | | | | | | | | | | |0|
135+
+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
136+
|0 |length |region |flags |
137+
+----+---------------------------------------------------------------+-------------------------------+-------------------------------+
138+
|1 |metadata |offset |
139+
+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
140+
| |6| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |3|3| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
141+
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
142+
| |3| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |2|1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|
143+
+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144+
145+
**Flags field - flags (Quad Word 0, bits 0:15)**
146+
147+
+-----+--------------------+------------------------------------------------------------------------------------------------+
148+
|Bits |Name |Functionality |
149+
+=====+====================+================================================================================================+
150+
|0 |MEMIF_DESC_FLAG_NEXT|Is chained buffer. When set, the packet is divided into multiple buffers. May not be contiguous.|
151+
+-----+--------------------+------------------------------------------------------------------------------------------------+
152+
153+
**Region index - region (Quad Word 0, 16:31)**
154+
155+
Index of memory region, the buffer is located in.
156+
157+
**Data length - length (Quad Word 0, 32:63)**
158+
159+
Length of transmitted/received data.
160+
161+
**Data Offset - offset (Quad Word 1, 0:31)**
162+
163+
Data start offset from memory region address. *.regions[desc->region].addr + desc->offset*
164+
165+
**Metadata - metadata (Quad Word 1, 32:63)**
166+
167+
Buffer metadata.
168+
169+
Files
170+
171+
- net/memif/memif.h *- descriptor and ring definitions*
172+
- net/memif/rte_eth_memif.c *- eth_memif_rx() eth_memif_tx()*
173+
174+
Example: testpmd
175+
----------------------------
176+
In this example we run two instances of testpmd application and transmit packets over memif.
177+
178+
First create ``master`` interface::
179+
180+
#./build/app/testpmd -l 0-1 --proc-type=primary --file-prefix=pmd1 --vdev=net_memif,role=master -- -i
181+
182+
Now create ``slave`` interface (master must be already running so the slave will connect)::
183+
184+
#./build/app/testpmd -l 2-3 --proc-type=primary --file-prefix=pmd2 --vdev=net_memif -- -i
185+
186+
Start forwarding packets::
187+
188+
Slave:
189+
testpmd> start
190+
191+
Master:
192+
testpmd> start tx_first
193+
194+
Show status::
195+
196+
testpmd> show port stats 0
197+
198+
For more details on testpmd please refer to :doc:`../testpmd_app_ug/index`.
199+
200+
Example: testpmd and VPP
201+
------------------------
202+
For information on how to get and run VPP please see `<https://wiki.fd.io/view/VPP>`_.
203+
204+
Start VPP in interactive mode (should be by default). Create memif master interface in VPP::
205+
206+
vpp# create interface memif id 0 master no-zero-copy
207+
vpp# set interface state memif0/0 up
208+
vpp# set interface ip address memif0/0 192.168.1.1/24
209+
210+
To see socket filename use show memif command::
211+
212+
vpp# show memif
213+
sockets
214+
id listener filename
215+
0 yes (1) /run/vpp/memif.sock
216+
...
217+
218+
Now create memif interface by running testpmd with these command line options::
219+
220+
#./testpmd --vdev=net_memif,socket=/run/vpp/memif.sock -- -i
221+
222+
Testpmd should now create memif slave interface and try to connect to master.
223+
In testpmd set forward option to icmpecho and start forwarding::
224+
225+
testpmd> set fwd icmpecho
226+
testpmd> start
227+
228+
Send ping from VPP::
229+
230+
vpp# ping 192.168.1.2
231+
64 bytes from 192.168.1.2: icmp_seq=2 ttl=254 time=36.2918 ms
232+
64 bytes from 192.168.1.2: icmp_seq=3 ttl=254 time=23.3927 ms
233+
64 bytes from 192.168.1.2: icmp_seq=4 ttl=254 time=24.2975 ms
234+
64 bytes from 192.168.1.2: icmp_seq=5 ttl=254 time=17.7049 ms

doc/guides/rel_notes/release_19_08.rst

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ New Features
6262
* Added support for SSE vector mode
6363
* Updated HWRM API to version 1.10.0.74
6464

65+
* **Added memif PMD.**
66+
67+
Added the new Shared Memory Packet Interface (``memif``) PMD.
68+
See the :doc:`../nics/memif` guide for more details on this new driver.
69+
6570

6671
Removed Items
6772
-------------

drivers/net/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_ICE_PMD) += ice
3535
DIRS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += ipn3ke
3636
DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe
3737
DIRS-$(CONFIG_RTE_LIBRTE_LIO_PMD) += liquidio
38+
DIRS-$(CONFIG_RTE_LIBRTE_PMD_MEMIF) += memif
3839
DIRS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4
3940
DIRS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5
4041
DIRS-$(CONFIG_RTE_LIBRTE_MVNETA_PMD) += mvneta

drivers/net/memif/Makefile

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright 2018-2019 Cisco Systems, Inc. All rights reserved.
3+
4+
include $(RTE_SDK)/mk/rte.vars.mk
5+
6+
#
7+
# library name
8+
#
9+
LIB = librte_pmd_memif.a
10+
11+
EXPORT_MAP := rte_pmd_memif_version.map
12+
13+
LIBABIVER := 1
14+
15+
CFLAGS += -O3
16+
CFLAGS += $(WERROR_FLAGS)
17+
CFLAGS += -DALLOW_EXPERIMENTAL_API
18+
# Experimantal APIs:
19+
# - rte_intr_callback_unregister_pending
20+
LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
21+
LDLIBS += -lrte_ethdev -lrte_kvargs
22+
LDLIBS += -lrte_hash
23+
LDLIBS += -lrte_bus_vdev
24+
25+
#
26+
# all source are stored in SRCS-y
27+
#
28+
SRCS-$(CONFIG_RTE_LIBRTE_PMD_MEMIF) += rte_eth_memif.c
29+
SRCS-$(CONFIG_RTE_LIBRTE_PMD_MEMIF) += memif_socket.c
30+
31+
include $(RTE_SDK)/mk/rte.lib.mk

0 commit comments

Comments
 (0)