Fix socket_id in rte_hash_parameters
[samplevnf.git] / VNFs / DPPD-PROX / prox_shared.c
1 /*
2 // Copyright (c) 2010-2020 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <rte_hash.h>
19 #include <rte_hash_crc.h>
20 #include <rte_version.h>
21
22 #include "quit.h"
23 #include "log.h"
24 #include "prox_shared.h"
25 #include "prox_globals.h"
26 #include "prox_compat.h"
27
28 #define INIT_HASH_TABLE_SIZE 8192
29
30 struct prox_shared {
31         struct rte_hash *hash;
32         size_t          size;
33 };
34
35 struct prox_shared sh_system;
36 struct prox_shared sh_socket[MAX_SOCKETS];
37 struct prox_shared sh_core[RTE_MAX_LCORE];
38
39 static char* get_sh_name(void)
40 {
41         static char name[] = "prox_sh";
42
43         name[0]++;
44         return name;
45 }
46
47 struct rte_hash_parameters param = {
48         .key_len = 256,
49         .hash_func = rte_hash_crc,
50         .hash_func_init_val = 0,
51         .socket_id = 0,
52 };
53
54 static void prox_sh_create_hash(struct prox_shared *ps, size_t size)
55 {
56         param.entries = size;
57         param.name = get_sh_name();
58         param.socket_id = rte_socket_id();
59         ps->hash = rte_hash_create(&param);
60         PROX_PANIC(ps->hash == NULL, "Failed to create hash table for shared data");
61         ps->size = size;
62         if (ps->size == INIT_HASH_TABLE_SIZE)
63                 plog_info("\tShared data tracking hash table created with size %zu\n", ps->size);
64         else
65                 plog_info("\tShared data tracking hash table grew to %zu\n", ps->size);
66 }
67
68 #if RTE_VERSION >= RTE_VERSION_NUM(2,1,0,0)
69 static int copy_hash(struct rte_hash *new_hash, struct rte_hash *old_hash)
70 {
71         const void *next_key;
72         void *next_data;
73         uint32_t iter = 0;
74
75         while (rte_hash_iterate(old_hash, &next_key, &next_data, &iter) >= 0) {
76                 if (rte_hash_add_key_data(new_hash, next_key, next_data) < 0)
77                         return -1;
78         }
79
80         return 0;
81 }
82 #endif
83
84 static int prox_sh_add(struct prox_shared *ps, const char *name, void *data)
85 {
86         char key[256] = {0};
87         int ret;
88
89         prox_strncpy(key, name, sizeof(key));
90         if (ps->size == 0) {
91                 prox_sh_create_hash(ps, INIT_HASH_TABLE_SIZE);
92         }
93
94 #if RTE_VERSION >= RTE_VERSION_NUM(2,1,0,0)
95         do {
96                 ret = rte_hash_add_key_data(ps->hash, key, data);
97                 if (ret < 0) {
98                         struct rte_hash *old = ps->hash;
99                         int success;
100                         do {
101                                 prox_sh_create_hash(ps, ps->size * 2);
102                                 success = !copy_hash(ps->hash, old);
103                                 if (success)
104                                         rte_hash_free(old);
105                                 else
106                                         rte_hash_free(ps->hash);
107                         } while (!success);
108                 }
109         } while (ret < 0);
110 #else
111                 PROX_PANIC(1, "DPDK < 2.1 not fully supported");
112 #endif
113         return 0;
114 }
115
116 static void *prox_sh_find(struct prox_shared *sh, const char *name)
117 {
118 #if RTE_VERSION >= RTE_VERSION_NUM(2,1,0,0)
119         char key[256] = {0};
120         int ret;
121         void *data;
122
123         if (!sh->hash)
124                 return NULL;
125
126         prox_strncpy(key, name, sizeof(key));
127         ret = rte_hash_lookup_data(sh->hash, key, &data);
128         if (ret >= 0)
129                 return data;
130 #else
131                 PROX_PANIC(1, "DPDK < 2.1 not fully supported");
132 #endif
133         return NULL;
134 }
135
136 int prox_sh_add_system(const char *name, void *data)
137 {
138         return prox_sh_add(&sh_system, name, data);
139 }
140
141 int prox_sh_add_socket(const int socket_id, const char *name, void *data)
142 {
143         if (socket_id >= MAX_SOCKETS)
144                 return -1;
145
146         return prox_sh_add(&sh_socket[socket_id], name, data);
147 }
148
149 int prox_sh_add_core(const int core_id, const char *name, void *data)
150 {
151         if (core_id >= RTE_MAX_LCORE)
152                 return -1;
153
154         return prox_sh_add(&sh_core[core_id], name, data);
155 }
156
157 void *prox_sh_find_system(const char *name)
158 {
159         return prox_sh_find(&sh_system, name);
160 }
161
162 void *prox_sh_find_socket(const int socket_id, const char *name)
163 {
164         if (socket_id >= MAX_SOCKETS)
165                 return NULL;
166
167         return prox_sh_find(&sh_socket[socket_id], name);
168 }
169
170 void *prox_sh_find_core(const int core_id, const char *name)
171 {
172         if (core_id >= RTE_MAX_LCORE)
173                 return NULL;
174
175         return prox_sh_find(&sh_core[core_id], name);
176 }