1 /* 2 * Copyright (C) 2017 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 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 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 84 ff_ipc_exit(void) 85 { 86 rte_eal_cleanup(); 87 return; 88 } 89 90 struct ff_msg * 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 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 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 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