Support packets in flight
[samplevnf.git] / VNFs / DPPD-PROX / lconf.h
1 /*
2 // Copyright (c) 2010-2017 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 #ifndef _LCONF_H_
18 #define _LCONF_H_
19
20 #include <rte_common.h>
21 #ifndef __rte_cache_aligned
22 #include <rte_memory.h>
23 #endif
24
25 #include "task_init.h"
26 #include "stats.h"
27
28 enum lconf_msg_type {
29         LCONF_MSG_STOP,
30         LCONF_MSG_START,
31         LCONF_MSG_DUMP,
32         LCONF_MSG_TRACE,
33         LCONF_MSG_DUMP_RX,
34         LCONF_MSG_DUMP_TX,
35         LCONF_MSG_RX_DISTR_START,
36         LCONF_MSG_RX_DISTR_STOP,
37         LCONF_MSG_RX_DISTR_RESET,
38         LCONF_MSG_TX_DISTR_START,
39         LCONF_MSG_TX_DISTR_STOP,
40         LCONF_MSG_TX_DISTR_RESET,
41         LCONF_MSG_RX_BW_START,
42         LCONF_MSG_RX_BW_STOP,
43         LCONF_MSG_TX_BW_START,
44         LCONF_MSG_TX_BW_STOP,
45 };
46
47 struct lconf_msg {
48         /* Set by master core (if not set), unset by worker after consumption. */
49         uint32_t            req;
50         enum lconf_msg_type type;
51         int                 task_id;
52         int                 val;
53 };
54
55 #define LCONF_FLAG_RX_DISTR_ACTIVE 0x00000001
56 #define LCONF_FLAG_RUNNING         0x00000002
57 #define LCONF_FLAG_TX_DISTR_ACTIVE 0x00000004
58 #define LCONF_FLAG_RX_BW_ACTIVE    0x00000008
59 #define LCONF_FLAG_TX_BW_ACTIVE    0x00000010
60 #define LCONF_FLAG_SCHED_RR    0x00000020
61
62 struct lcore_cfg {
63         /* All tasks running at the moment. This is empty when the core is stopped. */
64         struct task_base        *tasks_run[MAX_TASKS_PER_CORE];
65         uint8_t                 n_tasks_run;
66
67         void (*flush_queues[MAX_TASKS_PER_CORE])(struct task_base *tbase);
68
69         void (*period_func)(void *data);
70         void                    *period_data;
71         /* call periodic_func after periodic_timeout cycles */
72         uint64_t                period_timeout;
73
74         uint64_t                ctrl_timeout;
75         void (*ctrl_func_m[MAX_TASKS_PER_CORE])(struct task_base *tbase, void **data, uint16_t n_msgs);
76         struct rte_ring         *ctrl_rings_m[MAX_TASKS_PER_CORE];
77
78         void (*ctrl_func_p[MAX_TASKS_PER_CORE])(struct task_base *tbase, struct rte_mbuf **mbufs, uint16_t n_pkts);
79         struct rte_ring         *ctrl_rings_p[MAX_TASKS_PER_CORE];
80
81         struct lconf_msg        msg __attribute__((aligned(4)));
82         struct task_base        *tasks_all[MAX_TASKS_PER_CORE];
83         int                     task_is_running[MAX_TASKS_PER_CORE];
84         uint8_t                 n_tasks_all;
85         pthread_t               thread_id;
86
87         /* Following variables are not accessed in main loop */
88         uint32_t                flags;
89         uint8_t                 active_task;
90         uint8_t                 id;
91         char                    name[MAX_NAME_SIZE];
92         struct task_args        targs[MAX_TASKS_PER_CORE];
93         int (*thread_x)(struct lcore_cfg *lconf);
94         uint32_t                cache_set;
95 } __rte_cache_aligned;
96
97 extern struct lcore_cfg     *lcore_cfg;
98 extern struct lcore_cfg      lcore_cfg_init[];
99
100 /* This function is only run on low load (when no bulk was sent within
101    last drain_timeout (16kpps if DRAIN_TIMEOUT = 2 ms) */
102 static inline void lconf_flush_all_queues(struct lcore_cfg *lconf)
103 {
104         struct task_base *task;
105
106         for (uint8_t task_id = 0; task_id < lconf->n_tasks_all; ++task_id) {
107                 task = lconf->tasks_all[task_id];
108                 if (!(task->flags & TBASE_FLAG_TX_FLUSH) || (task->flags & TBASE_FLAG_NEVER_FLUSH)) {
109                         task->flags |= TBASE_FLAG_TX_FLUSH;
110                         continue;
111                 }
112                 lconf->flush_queues[task_id](task);
113         }
114 }
115
116 static inline void lconf_set_req(struct lcore_cfg *lconf)
117 {
118         (*(volatile uint32_t *)&lconf->msg.req) = 1;
119 }
120
121 static inline void lconf_unset_req(struct lcore_cfg *lconf)
122 {
123         (*(volatile uint32_t *)&lconf->msg.req) = 0;
124 }
125
126 static inline int lconf_is_req(struct lcore_cfg *lconf)
127 {
128         return (*(volatile uint32_t *)&lconf->msg.req);
129 }
130
131 /* Returns non-zero when terminate has been requested */
132 int lconf_do_flags(struct lcore_cfg *lconf);
133
134 int lconf_get_task_id(const struct lcore_cfg *lconf, const struct task_base *task);
135 int lconf_task_is_running(const struct lcore_cfg *lconf, uint8_t task_id);
136
137 int lconf_run(void *dummy);
138
139 void lcore_cfg_alloc_hp(void);
140
141 /* Returns the next active lconf/targ pair. If *lconf = NULL, the
142    first active lconf/targ pair is returned. If the last lconf/targ
143    pair is passed, the function returns non-zero. */
144 int core_targ_next(struct lcore_cfg **lconf, struct task_args **targ, const int with_master);
145 /* Same as above, but uses non-huge page memory (used before
146    lcore_cfg_alloc_hp is called). */
147 int core_targ_next_early(struct lcore_cfg **lconf, struct task_args **targ, const int with_master);
148
149 struct task_args *core_targ_get(uint32_t lcore_id, uint32_t task_id);
150
151 #endif /* _LCONF_H_ */