1 /*
2 * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 */
26
27 #include <rte_common.h>
28 #include <rte_memory.h>
29 #include <rte_config.h>
30 #include <rte_eal.h>
31 #include <rte_ring.h>
32 #include <rte_mempool.h>
33 #include <rte_malloc.h>
34 #include <unistd.h>
35
36 #include "ff_ipc.h"
37
38 static int inited;
39
40 static struct rte_mempool *message_pool;
41
42 uint16_t ff_proc_id = 0;
43
44 void
ff_set_proc_id(int pid)45 ff_set_proc_id(int pid)
46 {
47 if (pid < 0 || pid > 65535) {
48 printf("Invalid F-Stack proccess id\n");
49 exit(1);
50 }
51 ff_proc_id = pid;
52 }
53
54 int
ff_ipc_init(void)55 ff_ipc_init(void)
56 {
57 if (inited) {
58 return 0;
59 }
60
61 char *dpdk_argv[] = {
62 "ff-ipc", "-c1", "-n4",
63 "--proc-type=secondary",
64 /* RTE_LOG_WARNING */
65 "--log-level=5",
66 };
67
68 int ret = rte_eal_init(sizeof(dpdk_argv)/sizeof(dpdk_argv[0]), dpdk_argv);
69 if (ret < 0) {
70 rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
71 }
72
73 message_pool = rte_mempool_lookup(FF_MSG_POOL);
74 if (message_pool == NULL) {
75 rte_exit(EXIT_FAILURE, "lookup message pool:%s failed!\n", FF_MSG_POOL);
76 }
77
78 inited = 1;
79
80 return 0;
81 }
82
83 void
ff_ipc_exit(void)84 ff_ipc_exit(void)
85 {
86 rte_eal_cleanup();
87 return;
88 }
89
90 struct ff_msg *
ff_ipc_msg_alloc(void)91 ff_ipc_msg_alloc(void)
92 {
93 if (inited == 0) {
94 int ret = ff_ipc_init();
95 if (ret < 0) {
96 return NULL;
97 }
98 }
99
100 void *msg;
101 if (rte_mempool_get(message_pool, &msg) < 0) {
102 printf("get buffer from message pool failed.\n");
103 return NULL;
104 }
105
106 return (struct ff_msg *)msg;
107 }
108
109 int
ff_ipc_msg_free(struct ff_msg * msg)110 ff_ipc_msg_free(struct ff_msg *msg)
111 {
112 if (inited == 0) {
113 printf("ff ipc not inited\n");
114 return -1;
115 }
116
117 if (msg->original_buf) {
118 rte_free(msg->buf_addr);
119 msg->buf_addr = msg->original_buf;
120 msg->buf_len = msg->original_buf_len;
121 msg->original_buf = NULL;
122 }
123
124 rte_mempool_put(message_pool, msg);
125
126 return 0;
127 }
128
129 int
ff_ipc_send(const struct ff_msg * msg)130 ff_ipc_send(const struct ff_msg *msg)
131 {
132 int ret;
133
134 if (inited == 0) {
135 printf("ff ipc not inited\n");
136 return -1;
137 }
138
139 char name[RTE_RING_NAMESIZE];
140 snprintf(name, RTE_RING_NAMESIZE, "%s%u",
141 FF_MSG_RING_IN, ff_proc_id);
142 struct rte_ring *ring = rte_ring_lookup(name);
143 if (ring == NULL) {
144 printf("lookup message ring:%s failed!\n", name);
145 return -1;
146 }
147
148 ret = rte_ring_enqueue(ring, (void *)msg);
149 if (ret < 0) {
150 printf("ff_ipc_send failed\n");
151 return ret;
152 }
153
154 return 0;
155 }
156
157 int
ff_ipc_recv(struct ff_msg ** msg,enum FF_MSG_TYPE msg_type)158 ff_ipc_recv(struct ff_msg **msg, enum FF_MSG_TYPE msg_type)
159 {
160 int ret, i;
161 if (inited == 0) {
162 printf("ff ipc not inited\n");
163 return -1;
164 }
165
166 char name[RTE_RING_NAMESIZE];
167 snprintf(name, RTE_RING_NAMESIZE, "%s%u_%u",
168 FF_MSG_RING_OUT, ff_proc_id, msg_type);
169 struct rte_ring *ring = rte_ring_lookup(name);
170 if (ring == NULL) {
171 printf("lookup message ring:%s failed!\n", name);
172 return -1;
173 }
174
175 void *obj;
176 #define MAX_ATTEMPTS_NUM 1000
177 for (i = 0; i < MAX_ATTEMPTS_NUM; i++) {
178 ret = rte_ring_dequeue(ring, &obj);
179 if (ret == 0) {
180 *msg = (struct ff_msg *)obj;
181 break;
182 }
183
184 usleep(1000);
185 }
186
187 return ret;
188 }
189